public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: Magal Baz <baz.magal@gmail.com>
To: gcc-bugs@gcc.gnu.org
Subject: Stack Canary Security Issue in gcc-arm-none-eabi-9
Date: Thu, 18 May 2023 11:46:31 +0100	[thread overview]
Message-ID: <CAOfEGGN=ZdScgqsYonVzsgEScHR_TY2eVPVQ4TFYZrmBYG=zCw@mail.gmail.com> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 2810 bytes --]

Hello,

I encountered a security issue affecting gcc-arm-none-eabi-9, causing it to
produce ineffective stack protection. The issue is public as it was
described in a blog on May 2021
https://blog.inhq.net/posts/faulty-stack-canary-arm-systems/ by Christian
Reitter. However it was never reported as a bug in an active platform*, so
no fix was issued and no CVE was assigned to it.

As this is a major security issue I think it would be good if a CVE was
issued to alert developers and vendors still using GCC 9.

Short issue description (see Reitter's blog for comprehensive details):

Older versions of gcc-arm-none-eabi, such as
gcc-arm-none-eabi-9-2019-q4-major, have a bug where the global address of
the stack guard is placed on the stack as a canary rather than the actual
value of the stack guard. This undermines the purpose of the protection as
it makes the canary value knowable. In addition, the embedded environments
that this toolchain targets often lack Address Space Layout Randomization,
meaning the global guard address is in itself constant, making the
protection entirely ineffective.


See the following code and results built with
gcc-arm-none-eabi-9-2019-q4-major and targeting arm cortex m-33.

*Code (also attached as check_stack_protection.c):*

extern uint32_t *__stack_chk_guard;
bool check_stack_bug(uint32_t const *data, int dump_len)
{
    for (int i = 0; i < dump_len; i++)
    {
        console_printf("%p : %p\n", &data[i], data[i]);
        if (data[i] == (const uint32_t)&__stack_chk_guard)
        {
            console_printf(
                "canary is at offset %d from dummy and equals to the
address of __stack_chk_guard\n",
                i);
            return true;
        }
    }
    return false;
}

static int app_stack_guard_cmd_handler()
{

    // A dummy var to get the stack frame address
    uint32_t dummy = 0x57AC57AC;

    bool is_buggy = check_stack_bug((uint32_t const *)&dummy, 5);
    if (is_buggy)
        console_printf("stack protection bug detected\n");
}


*output (also attached as output.c):*

Stack dump:
0x2013bdb8 : 0x57ac57ac
0x2013bdbc : 0x2012f83c
canary is at offset 1 from dummy and equals to the address of
__stack_chk_guard
stack protection bug detected


*binary (also attached as binary_prologue_epiloguge.txt):*
Canary setting:
   8ad48: 1a 4a         ldr r2, [pc, #104]
   8ad4a: 83 b0         sub sp, #12
   8ad4c: 12 68         ldr r2, [r2]
   8ad4e: 01 92         str r2, [sp, #4]

canary check:
   8ad8a: 0a 4b         ldr r3, [pc, #40]
   8ad8c: 1a 68         ldr r2, [r3]
   8ad8e: 01 9b         ldr r3, [sp, #4]
   8ad90: 5a 40         eors r2, r3

Thank you,

Magal Baz











*It reported in an appeartnly inactive platform in 2020
https://answers.launchpad.net/gcc-arm-embedded/+question/689391 by Daniel
Worley.

[-- Attachment #2: binary_prologue_epilogue.txt --]
[-- Type: text/plain, Size: 386 bytes --]


   8ad48: 1a 4a        	ldr	r2, [pc, #104]          @ 0x8adb4 <$d+0x4>
   8ad4a: 83 b0        	sub	sp, #12
   8ad4c: 12 68        	ldr	r2, [r2]
   8ad4e: 01 92        	str	r2, [sp, #4]

canary check:
   8ad8a: 0a 4b        	ldr	r3, [pc, #40]           @ 0x8adb4 <$d+0x4>
   8ad8c: 1a 68        	ldr	r2, [r3]
   8ad8e: 01 9b        	ldr	r3, [sp, #4]
   8ad90: 5a 40        	eors	r2, r3

[-- Attachment #3: check_stack_protection.c --]
[-- Type: application/octet-stream, Size: 752 bytes --]

extern uint32_t *__stack_chk_guard;

bool check_stack_bug(uint32_t const *data, int dump_len)
{
    for (int i = 0; i < dump_len; i++)
    {
        console_printf("%p : %p\n", &data[i], data[i]);
        if (data[i] == (const uint32_t)&__stack_chk_guard)
        {
            console_printf(
                "canary is at offset %d from dummy and equals to the address of __stack_chk_guard\n",
                i);
            return true;
        }
    }
    return false;
}

static int app_stack_guard_cmd_handler()
{

    // A dummy var to get the stack frame address
    uint32_t dummy = 0x57AC57AC;

    bool is_buggy = check_stack_bug((uint32_t const *)&dummy, 5);
    if (is_buggy)
        _console_printf("stack protection bug detected\n");
}

[-- Attachment #4: output.txt --]
[-- Type: text/plain, Size: 170 bytes --]

Stack dump:
0x2013bdb8 : 0x57ac57ac
0x2013bdbc : 0x2012f83c
canary is at offset 1 from dummy and equals to the address of __stack_chk_guard
stack protection bug detected

             reply	other threads:[~2023-05-18 10:46 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-18 10:46 Magal Baz [this message]
2023-05-18 11:01 ` Jonathan Wakely
2023-05-18 11:03   ` Jonathan Wakely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOfEGGN=ZdScgqsYonVzsgEScHR_TY2eVPVQ4TFYZrmBYG=zCw@mail.gmail.com' \
    --to=baz.magal@gmail.com \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).