0

In our GCC-based C embedded system we are using the -ffunction-sections and -fdata-sections options to allow the linker, when linking the final executable, to remove unused (unreferenced) sections. This works well since years.

In the same system most of the data-structures and buffers are allocated statically (often as static-variables at file-scope).

Of course we have bugs, sometimes nasty ones, where we would like to quickly exclude the possibility of buffer-overflows.

One idea we have is to place canaries in between each bss-section and data-section - each one presenting exactly one symbol (because of -fdata-sections). Like the compiler is doing for functions-stacks when Stack-Smashing and StackProtection is activated. Checking these canaries could be done from the host by reading the canary-addresses "from time to time".

It seems that modifying the linker-script (placing manually the section and adding a canary-word in between) seems feasible, but does it make sense?

Is there a project or an article in the wild? Using my keywords I couldn't find anything.

Patrick B.
  • 11,773
  • 8
  • 58
  • 101
  • 2
    Well, you probably know yourself that this doesn't replace secure programming and code audits, but of course it might help to detect buffer overflows and prevent exploits or misbehaving systems in some cases. Of course, checking the canaries in short time intervals is necessary and may put an unwanted load or latency on the systems (especially embedded ones with low capacity). – Ctx Jan 28 '20 at 15:08
  • Secure programming and code audits and coding standards do not prevent bugs. At least not in C, hence our idea. – Patrick B. Jan 28 '20 at 15:53
  • 1
    Of course they prevent bugs. If they prevent _all_ bugs depends on how diligently these actions are performed and on how complex the code is. – Ctx Jan 28 '20 at 15:56
  • 1
    "Secure programming and code audits and coding standards do not prevent bugs" Then you are doing it wrong. Stepping the organization up to have peer review, adopting a sounds coding standard like MISRA-C, then add checks with static analysis tools are all very effective ways of increasing code quality. At the expense of time to market, because although they are effective, these things tend to consume a lot of time and patience. – Lundin Jan 28 '20 at 15:59
  • I should have said "do not prevent all bugs". – Patrick B. Jan 28 '20 at 16:27

1 Answers1

2

Canaries are mostly useful for the stack, since it expands and collapses beyond the programmer's direct control. The things you have on data/bss do not behave like that. Either they are static variables, or in case they are buffers, they should keep within their fixed size, which should be checked with defensive programming in-place with the algorithm, rather than unorthodox tricks.

Also, stack canaries are used specifically in RAM-based, PC-like systems that don't know any better way. In embedded systems, they aren't very meaningful. Some useful things you can do instead:

  • Memory map the stack so that it grows into a memory area where writes will yield a hardware exception. Like for example, if your MCU has the ability to separate executable memory from data memory and yield exceptions if you try to execute code in the data area, or write to the executable area.
  • Ensure that everything in your program dealing with buffers perform their error checks and not write out-of-bounds. Static analysis tools are usually decent at spotting out-of-bounds bugs. Even some compilers can do this.
  • Add lots of defensive programming with static asserts. Check sizes of structs, buffers etc at compile-time, it's free.
  • Run-time defensive programming. For example if(x==good) {...} else if(x == bad) {... } is missing an else. And switch(x) case A: { ... } is missing a default. "But it can't go there in theory!" No but in practice, when you get runaway code caused by bugs (very likely), data retention of flash (100% likely) or EMI influence on RAM (quite unlikely).
  • And so on.
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • So your answer to my question is no, not useful? – Patrick B. Jan 28 '20 at 16:27
  • In an ideal world we have control on everything. In our world we have proprietary code using (static) buffers we hand in and we don't know what's happening. Thanks for your proposed alternatives which are good practice indeed. – Patrick B. Jan 28 '20 at 16:33
  • @PatrickB. Not particularly useful, no. Just as tossing in fixed byte sync words in RS-232 protocols, instead of fixing the underlying problem - namely that RS-232 isn't very rugged and another technology should have been used instead. Deal with the root cause if the error, not with error symptoms. – Lundin Jan 29 '20 at 07:32