Live data from Hacker News

How to zero a buffer

daemonology.net

171–180 of 216 posts

Re: How to zero a buffer

#171

Slightly OT since it has little to do with security, but fighting the optimizer is something FPGA Verilog and VHDL designers must also master. If you don't use an the result of some logic it will be optimized out. One way to prevent this is to route it to a pin. If logic is fed by a constant, it will be optimized out right up to the point where the result of the logic is mixed with some external input. (early tools c…

Why would you want your FPGA to have circuits that aren't used? And why don't you want constant expressions to be pre-calculated by the optimizer?

I have the exact same question.

I presume this is for some incremental development work. Like testing and seeing the number of gates/pins used for a design but you need to feed the logic with constant placeholders.

Re: How to zero a buffer

#172
post #136

Is the proposed solution really the best approach? It seems complicated to me and relies on obscure parts of the language. Maybe the problem (compiler optimizes away function call because the result is no longer needed) could be solved like this: memset(key, 0, sizeof(key)); if (key[0]) // we are using key, so you can't skip memset() dropDead(); Unless the compilers "understand" memset and still optimize away the las…

It's not even that it 'understands' memset, more likely that the memset call is almost immediately inlined into your code making it obvious what's going on.

Re: How to zero a buffer

#173
Does anyone have any advice on articles about C compiler optimizations in general (especially gcc)? I'm doing my first serious C work in ten years, and I keep wondering if I should fuss with things like this or let the compiler handle it all:

    foo->bar->baz[i].oof = foo->bar->baz[i].durb + meep;
vs

   what *tmp = foo->bar->baz[i];
   tmp->oof = tmp->durb + meep;
EDIT: I'm not asking for a link to this:

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

I'm asking if there is advice about it. Any overviews with common pitfalls, advice on when to use -O1 vs -O2, specific optimizations to turn on/off, etc.

Re: How to zero a buffer

#176

Earlier quoted context omitted.

There are two different things you can mean when you say "C is not suitable to these kinds of applications". One is the more extreme, "You should not be using C, you should be using because it is more suitable." That's a bit of a hard sell; though specific alternatives should be evaluated on their merits. There is also, "there are design choices that have been made in C that make it worse for these applications than…

The funny thing to me is that the standard crypto packages for other languages nearly always end up calling C code.

That's not at all incompatible with "C is the best option of existing languages, but still bad in some obvious ways where it could be better (for this purpose)."

Re: How to zero a buffer

#177

Does anyone have any advice on articles about C compiler optimizations in general (especially gcc)? I'm doing my first serious C work in ten years, and I keep wondering if I should fuss with things like this or let the compiler handle it all: foo->bar->baz[i].oof = foo->bar->baz[i].durb + meep; vs what *tmp = foo->bar->baz[i]; tmp->oof = tmp->durb + meep; EDIT: I'm not asking for a link to this: https://gcc.gnu.org/o…

    foo->bar->baz[i].oof = foo->bar->baz[i].durb + meep;
This is fine, no need to "optimize" anything. This kind of common subexpression elimination should be done by any modern compiler (for any language!) and the algorithm behind it is taught in university classes too.

Most of the time it's safe to use -O3. If you're doing numerical code with floating points -ffast-math is also pretty safe if your code is correct (ie. no NaN/Inf bugs). Almost the only reason to turn off optimization (-O0) is when higher optimizations make using a debugger harder.

Here's a pretty nice article with some specific optimizations that GCC can (or can't) do. It's pretty old, though, the examples were done with GCC 4.2.1, current version is around 4.9.

http://ridiculousfish.com/blog/posts/will-it-optimize.html

These days Clang can be as good or better than GCC most of the time. The exceptions are in more exotic code like kernel space stuff or micro controller programming.

There's no room for guesswork if you actually want to optimize code, so spend some time reading the assembler output from your compiler as well as benchmarking the results. I usually use objdump -d objfile.o to look at assembly output.

Re: How to zero a buffer

#178

Earlier quoted context omitted.

There's basically only one (or a family of) languages that have no optimisation at all, and enable complete control over what the machine does - Asm. The code you get is exactly the code you write, no matter how efficient or inefficient it is. This also enables much better the prevention of other attacks like timing/power analysis, since you can effectively insert dummy instructions as needed to keep the timing and p…

"There's basically only one (or a family of) languages that have no optimisation at all" ... sort of. Chips themselves perform some optimizations.

I think I heard of a timing attack that was introduced by CPU optimizations, not in the underlying code at all! But I can't remember what research that was and maybe I'm confusing two different issues.

Re: How to zero a buffer

#179
post #118
post #111

Why would you want to zero a buffer ? Because it may contain sensitive information, I presume. If you don't have additional properties w.r.t allocated memory, what prevent a system with high load to temporarily put the given memory block on swap, leaking the information on disk ? Security is hard...

>Why would you want to zero a buffer ? Because it may contain sensitive information, I presume. You don't zero sensitive buffers. You randomize them, then free() them.

A dead store is a dead store. It doesn't matter whether you write something random into it or zero. If the compiler notices that you cannot read it again anyway, it will elide the write.

Re: How to zero a buffer

#180

Does anyone have any advice on articles about C compiler optimizations in general (especially gcc)? I'm doing my first serious C work in ten years, and I keep wondering if I should fuss with things like this or let the compiler handle it all: foo->bar->baz[i].oof = foo->bar->baz[i].durb + meep; vs what *tmp = foo->bar->baz[i]; tmp->oof = tmp->durb + meep; EDIT: I'm not asking for a link to this: https://gcc.gnu.org/o…

That's basic dataflow analysis. Unless one of those pointers is to a volatile object, I'd be very surprised if any halfway serious compiler produced more than one access to

  foo->bar->baz[i]
unless "meep" has side effects.

To address the question, these some of the guidelines I try to follow:

- Compile with "-Wall -Wextra" (and "-pedantic" if feasible)

- Modularize your code. You can always mark functions "static inline."

- Don't try to be clever; "Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?" In fact, Kernighan has a lot of good advice: https://en.wikipedia.org/wiki/The_Elements_of_Programming_St....

- Be careful with signed integers. Overflow can do weird things to your program. You can make signed integers act like unsigned integers on overflow using -fwrapv, but if that behaviour is correct, you probably should have used an unsigned integer outright.

- Be careful with pointers; specifically, the requirements of any pointer passed to a function should be explicitly documented: whether it is allowed to be null, whether it's an "in" parameter or an "out" parameter, whether it points to one object or an array, etc. If a pointer points to an array, carry a length parameter with it; null-termination is really easy to foul up.

- Don't optimize until the program needs to be faster. When it does, profile and target the low-hanging fruit. Personally, I usually use either -O0 or -Ofast, depending on whether or not I'm debugging something (-Og is a good one if you need speed while debugging).

- Speaking of optimization, don't underestimate the power of inlining. It's easy to go overboard with it, but it can make a big difference in the right situations.

- Your compiler probably has a peephole optimizer. Replacing "i / 16" with "i >> 4" is probably not an improvement to the quality of either the source code or the object code.

- If you find yourself reimplementing something that C++ knows how to do, consider using C++ to do that. It's not always politically feasible, but remember that you can link C and C++ code.

Post reply on HN