Live data from Hacker News

How to zero a buffer

daemonology.net

191–200 of 216 posts

Re: How to zero a buffer

#191
post #139

Just put it in a shared library and don't worry about it. Why all these compiler-specific brittle solutions when simply putting a function in a .so will ensure it's being called and will prevent any link-time optimisations.

Last time I checked, there was nothing specifically preventing an implementation of C from doing whole-program optimization at runtime, even to the point of dynamic library calls.

So: this is not something you can rely on always working. Yes, it works currently, but it is not guaranteed to always do so.

Re: How to zero a buffer

#192
post #178

Earlier quoted context omitted.

"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.

Certainly plausible. If the CPU optimizes one path but not another, in principle that's some information. In practice, gathering enough data to get that above the noise floor and turning it into something useful besides would certainly be difficult but maybe not too difficult.

Re: How to zero a buffer

#193
post #160
post #58

Earlier quoted context omitted.

How about compilers having a way for us to tell it that a particular function must not be removed? It seems silly that we have to come up with hacks to work around the compiler.

They do. Every function they don't know about is considered important, potentially having side effects and the call will remain. Just call a function that exists in a library somewhere else (but use a static library and link-time optimization and that goes wrong again, because the optimizer knows the function then).

Or, for that matter, use a dynamic library and it can still go wrong! (hypothetical future JITter or somesuch)

Re: How to zero a buffer

#194

Earlier quoted context omitted.

From the article, "Some people will try this with secure_memzero in a separate C file. This will trick yet more compilers, but no guarantees — with link-time optimization the compiler may still discover your treachery." https://gcc.gnu.org/wiki/LinkTimeOptimization http://llvm.org/docs/LinkTimeOptimization.html

Move the func into a dynamically linked library. Thanks to the performance requirements of dynamic linking it's going to be a really long time until we have dynamic linker peeking into .so files and checking what a func does.

...but still not guaranteed, which is what this is striving for.

Re: How to zero a buffer

#195
It seems like ideally what we need is a language designed for as-fast-as-secure computation, JIT for the specific architecture it is going to run on to ensure no differences in timing, energy use, or anything (within whatever bounds are achievable) even in the face of different cache layouts, CPU optimizations and similar and which makes it a point to clean up everything that is not meant to be returned.

Re: How to zero a buffer

#196
post #177

Earlier quoted context omitted.

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.…

>I usually use objdump -d objfile.o to look at assembly output You can also compile to assembly with -S. I think it's clearer that way.

Yes, I know about the -S flag. But CFLAGS, etc comes from Makefiles so inspecting the object files (which I already have) is easier than re-invoking the compiler with -S added to the command line.

Re: How to zero a buffer

#197
post #177

Earlier quoted context omitted.

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.…

Really appreciate everyone's replies! A related question about my example: what if I want to assign the pointer dereference to `tmp` to improve readability (rather than avoid multiple traversals). Is there any reason not to use a tmp variable (presumably with a better name)?

No, it doesn't hurt to have an extra local variable if you have compiler optimization enabled. If it would be a global or member of struct/class, that's a different deal.

It's useful to add some variables to be inspected in the debugger.

Re: How to zero a buffer

#198

Earlier quoted context omitted.

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)."

True.

Re: How to zero a buffer

#199
post #189

Earlier quoted context omitted.

If you have multiple threads accessing a shared (mutable) variable in your program, even a shared volatile variable, then you need to guard every access to that variable (which, in this case, includes every function call through memset_ptr) with proper thread synchronisation primitives. Marking a variable "volatile" is not enough to prevent data races in a multi-threaded environment. If you've put a semaphore, or mut…

I think you missed my point. memset_ptr is a const (not changed by this program... theoretically) volatile (allowed to be changed by the system, theoretically) pointer to memset. In THIS PARTICULAR CASE, memset_ptr points to memset. The compiler however doesn't know that it won't change due to another processes, but we do. So the compiler shouldn't be able to optimize out the call directly to the function pointer bec…

That race exists regardless. Many systems will execute this as loading the pointer into a register, them jumping to it. The value could change between those two instructions.

Re: How to zero a buffer

#200

Why would the compiler be allowed optimize away a call to a perfectly valid function? This seems like it's allowing to compiler to make judgement calls on whether or not your code is worthy of being executed.

The "result" of compiling a C program is defined in terms of observable behavior. It's mostly stuff like IO and writes to `volatile` variables and that sort of thing. There's no presumption of any sort of correspondence between the source code and the generated code and really a compiler can emit whatever, except that the observable behavior must be the same as that of a translation that actually follows the language definition.

Since there's no accounting for shenanigans like using a debugger to look at variables that are never accessed anymore or dumping the entire stack to a file at arbitrary points etc, the compiler is free to consider code unworthy of being executed if it provably doesn't contribute to further observable behavior of your program.

Post reply on HN