ASAN on embedded platform (Cortex-M) ?

1,484 views
Skip to first unread message

Thomas Legrand

unread,
Mar 19, 2019, 9:06:43 AM3/19/19
to address-sanitizer

Hello,

 

I’m totally new to ASAN, I’m using latest GCC ARM compiler for embedded projects.

I was wondering if someone already tried to use ASAN on embedded platforms like Cortex-M ?

I tried adding “-fsanitize=address” to my compile/link command line and it compiled fine but failed at linking because of missing functions (__asan_*).

 

Is it “doable” to implement these ?

I guess there are 2 options, do checks on the target itself (but what is the required RAM/FLASH/CPU footprint ?) and trigger e.g. a breakpoint on error, or transfer data to a PC for calculations (but what would be the required bandwidth ?) but that would require developing a dedicated GUI/app.

 

Any advice ?

 

Thomas.

Alexander Potapenko

unread,
Mar 19, 2019, 9:38:27 AM3/19/19
to address-...@googlegroups.com
On Tue, Mar 19, 2019 at 2:06 PM Thomas Legrand <otat...@gmail.com> wrote:
>
> Hello,
>
>
>
> I’m totally new to ASAN, I’m using latest GCC ARM compiler for embedded projects.
>
> I was wondering if someone already tried to use ASAN on embedded platforms like Cortex-M ?
No idea, but at least it's not officially supported.

> I tried adding “-fsanitize=address” to my compile/link command line and it compiled fine but failed at linking because of missing functions (__asan_*).
>
>
>
> Is it “doable” to implement these ?
It's probably doable, but depends on how much control over the
standard library and the loaded program you have on the target
platform.
You'll need to implement an ASan runtime library that at least:
- kicks in early (preferably before any of the instrumented code is
executed) and reserves 1/8 of the memory for ASan shadow (you'll need
to look at asan.c in GCC to find out the exact addresses);
- wraps malloc() and free() in order to unwind and store the stack
and unpoison/poison shadow for the memory region;
- implements the error reporting functions. Sending data to a PC
sounds more feasible, as you probably don't have any debug info on the
target chip.

I don't know though, how much memory your platform has. As written
above, ASan takes 1/8 for the shadow, plus some unpredictable amount
of memory for the redzones (which have to be added to every
allocation), plus some tunable amount for the quarantine (for
simplicity I suggest you don't implement it at first). ASan also adds
quite a bit of boilerplate to the code, so some programs may stop
fitting into the flash memory.

> I guess there are 2 options, do checks on the target itself (but what is the required RAM/FLASH/CPU footprint ?) and trigger e.g. a breakpoint on error, or transfer data to a PC for calculations (but what would be the required bandwidth ?) but that would require developing a dedicated GUI/app.
>
>
>
> Any advice ?
>
>
>
> Thomas.
>
> --
> You received this message because you are subscribed to the Google Groups "address-sanitizer" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to address-saniti...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

Thomas Legrand

unread,
Mar 19, 2019, 12:46:15 PM3/19/19
to address-sanitizer
Hello,

Thanks a lot for the reply.

I have total control over the loaded program:
- running code before startup is no problem
- reserving 1/8th the memory seems doable (I can change the linker script to split the memory regions)
- I do not use any malloc / free in my applications (new keyword only with specified custom allocators, or placement new)
- for error reporting, triggering a hardware breakpoint seems ok to me (I already do that for e.g. failing assert), so that I have full stack trace, etc. and I wouldn't use ASAN "unattended" (without debug probe attached)
- flash size should be ok, I see that more as a debug tool so I can remove parts of the application if needed to fit in flash (but on some project I wouldn't be able to test the full application, that's right)

I just checked asan.c and it's probably much much overkill to try to implement everything (and probably not possible with embedded contraints).

But looking at the ARM GCC compiler errors when I add the -fsanitize=address switch, it doesn't seem to call that much different methods:
- __asan_report_storeN
- __asan_report_loadN
- __asan_handle_no_return
- __asan_report_store_n
- __asan_report_load_n
- __asan_stack_malloc_N
- __asan_stack_free_N
- __asan_option_detect_stack_use_after_return
- __asan_after_dynamic_init
- __asan_before_dynamic_init

Maybe I could make good use of this automatic instrumentation to catch at least some bugs. 
Do you know where I could find the use and signature of these ?

Thomas.

Alexander Potapenko

unread,
Mar 19, 2019, 12:55:04 PM3/19/19
to address-...@googlegroups.com
On Tue, Mar 19, 2019 at 5:46 PM Thomas Legrand <otat...@gmail.com> wrote:
>
> Hello,
>
> Thanks a lot for the reply.
>
> I have total control over the loaded program:
> - running code before startup is no problem
> - reserving 1/8th the memory seems doable (I can change the linker script to split the memory regions)
> - I do not use any malloc / free in my applications (new keyword only with specified custom allocators, or placement new)
> - for error reporting, triggering a hardware breakpoint seems ok to me (I already do that for e.g. failing assert), so that I have full stack trace, etc. and I wouldn't use ASAN "unattended" (without debug probe attached)
> - flash size should be ok, I see that more as a debug tool so I can remove parts of the application if needed to fit in flash (but on some project I wouldn't be able to test the full application, that's right)
>
> I just checked asan.c and it's probably much much overkill to try to implement everything (and probably not possible with embedded contraints).
>
> But looking at the ARM GCC compiler errors when I add the -fsanitize=address switch, it doesn't seem to call that much different methods:
> - __asan_report_storeN
> - __asan_report_loadN
> - __asan_handle_no_return
> - __asan_report_store_n
> - __asan_report_load_n
> - __asan_stack_malloc_N
> - __asan_stack_free_N
> - __asan_option_detect_stack_use_after_return
> - __asan_after_dynamic_init
> - __asan_before_dynamic_init
>
> Maybe I could make good use of this automatic instrumentation to catch at least some bugs.
> Do you know where I could find the use and signature of these ?
You can take a look here:
https://github.com/llvm-mirror/compiler-rt/tree/master/lib/asan (it
should be somewhere in GCC as well, but LLVM repo is the source of
truth)
Guess you won't be able to compile ASan runtime for your arch
directly, but it can give you an idea of what's going on.
Most certainly you won't need complicated stuff like thread support,
env-based options, even the fancy malloc.
You can also start with disabling most of ASan instrumentation
(https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html, more
in asan.c in GCC), so that less of those functions are emitted.
> Thomas.
>
>
> On Tuesday, March 19, 2019 at 2:06:43 PM UTC+1, Thomas Legrand wrote:
>>
>> Hello,
>>
>>
>>
>> I’m totally new to ASAN, I’m using latest GCC ARM compiler for embedded projects.
>>
>> I was wondering if someone already tried to use ASAN on embedded platforms like Cortex-M ?
>>
>> I tried adding “-fsanitize=address” to my compile/link command line and it compiled fine but failed at linking because of missing functions (__asan_*).
>>
>>
>>
>> Is it “doable” to implement these ?
>>
>> I guess there are 2 options, do checks on the target itself (but what is the required RAM/FLASH/CPU footprint ?) and trigger e.g. a breakpoint on error, or transfer data to a PC for calculations (but what would be the required bandwidth ?) but that would require developing a dedicated GUI/app.
>>
>>
>>
>> Any advice ?
>>
>>
>>
>> Thomas.
>

Konstantin Serebryany

unread,
Mar 19, 2019, 1:18:12 PM3/19/19
to address-sanitizer
IIUC, Cortex-M is a 32-bit system, right? 
asan's memory consumption is typically around 2x: you have redzones, quarantine, 1/8 for the shadow, and some bookkeeping overhead. 
You can reduce most of it at the expense of bug report quality and bug detection probability, but probably it will remain at least 50%. 

It's another flavor of asan, with a much smaller RAM overhead, typically < 10%.
The current implementation is 64-bit only, but if you fully control all of your source code, don't have too many assembly blobs,
 and if you can squeeze your address space into ~ 28 bits, this scheme may work for you too. 



Reply all
Reply to author
Forward
0 new messages