News for hackers. Stuff that matters.
Re:How to zero a buffer by cperciva on Thursday September 04, 2014 @07:21PM (#8271272)
The term "observable behaviour" is defined in the standard: Essentially, I/O to files and interactive devices, plus accesses to volatile objects.
Re:How to zero a buffer by schoen on Thursday September 04, 2014 @07:38PM (#8271358)
Perhaps in retrospect this was an inappropriate choice of definition, at least for cryptographic operations.
Re:How to zero a buffer by bunderbunder on Thursday September 04, 2014 @07:59PM (#8271457)
I'm gonna go ahead and say it: Perhaps in retrospect C is an inappropriate choice of language for these kinds of applications.

This "Performance at all costs, including safety and predictability" thing may be appropriate in video games, but for security-critical applications that philosophy is downright negligent.

Re:How to zero a buffer by tedunangst on Thursday September 04, 2014 @08:05PM (#8271482)
I'm not aware of any language that would be better. Most languages don't even let you touch memory to try to zero it.
Re:How to zero a buffer by userbinator on Friday September 05, 2014 @01:13AM (#8272426)
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 power well-behaved.

The biggest downside I see is that it's non-portable, but the reality is that there's not all that many architectures out there to port to anyway (x86, ARM, MIPS probably covers 90%+) and for truly security-critical code having that level of control could be worth it. (This also avoids the "trusting the compiler" problem - an assembler is far easier to verify correctness of than even the simplest C compiler...)

Re:How to zero a buffer by dllthomas on Friday September 05, 2014 @01:43AM (#8272493)
"There's basically only one (or a family of) languages that have no optimisation at all"

... sort of. Chips themselves perform some optimizations.

Re:How to zero a buffer by schoen on Friday September 05, 2014 @12:30PM (#8274779)
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 by dllthomas on Friday September 05, 2014 @01:08PM (#8274993)
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 by schoen on Friday September 05, 2014 @03:30PM (#8275837)
I might be thinking of some of the cache timing issues about sharing physical hardware with other guest VMs. There were papers in the last two years showing circumstances in which another VM on the same device can learn about secrets in caches via timing experiments. But that's a cache issue rather than a general pipeline issue. So I still can't remember if there's something else that I'm thinking of or if I'm just confusing it with the cache stuff.

http://blog.cryptographyengineering.com/2012/10/attack-of-we...

More recent stuff in this vein:

https://eprint.iacr.org/2014/435.pdf

(Yikes!)

Re:How to zero a buffer by TheLoneWolfling on Friday September 05, 2014 @07:15PM (#8276800)
Well, the most obvious form of that is cache.

There's a entire class of timing attacks that rely on the CPU cache - they would not exist if CPUs didn't do the optimization of storing local copies of limited sections of RAM.

Re:How to zero a buffer by bunderbunder on Thursday September 04, 2014 @08:56PM (#8271728)
A language that wouldn't give you a way to zero out data wouldn't be appropriate for security-critical tasks either.

Just like how a language that doesn't do array bounds checking and permits pointer math (read: a language where buffer overflows are a damn feature) isn't appropriate for security critical tasks.

Just like how a language that must be actively fought using clever hacks in order to prevent it from undermining your attempts to guard against common exploit vectors isn't appropriate for security critical tasks.

Re:How to zero a buffer by ufo on Thursday September 04, 2014 @09:18PM (#8271813)
Zeroing out an array or struct field is not a C-specific feature.
Re:How to zero a buffer by tedunangst on Thursday September 04, 2014 @09:52PM (#8271925)
Dead store elision is not a C specific optimization.
Re:How to zero a buffer by jacksingleton on Thursday September 04, 2014 @11:39PM (#8272206)
This is what Mozilla is trying to create with Rust

http://www.rust-lang.org/

Re:How to zero a buffer by swift on Thursday September 04, 2014 @08:33PM (#8271638)
Many languages zero every allocation unless they can prove that you immediately write over that memory without reading it.
Re:How to zero a buffer by marvy on Thursday September 04, 2014 @08:48PM (#8271699)
Yes, but that's going the wrong direction. The situation here is that you've already written over it, and now wish to erase what you wrote.
Re:How to zero a buffer by tedunangst on Thursday September 04, 2014 @08:47PM (#8271690)
Which does nothing for memory which has been freed but not reallocated.
Re:How to zero a buffer by swift on Sunday September 07, 2014 @02:05AM (#8280453)
That's a great point; should've thought through that post a little better. Thanks.
Re:How to zero a buffer by pcwalton on Thursday September 04, 2014 @11:39PM (#8272207)
Dead store elimination is a really important optimization, and it comes out of bog-standard compiler optimizations like SROA on SSA form IR. You really want your compiler to perform it for acceptable performance.
Re:How to zero a buffer by bunderbunder on Friday September 05, 2014 @12:29AM (#8272316)
Yes. But dead store elimination combined with being allowed to dereference arbitrary pointers and leaving newly allocated blocks of memory uninitialized is problematic. Contrary to what the C standard would like us to believe, those other features do mean that dead store elimination alters the semantics of a program. It doesn't impact the semantics of the procedure whose dead stores are being eliminated, but it alters the semantics of arbitrary operations elsewhere in the program because it could influence the result I get when I dereference a pointer dereference or examine the contents of a newly-allocated block of memory.

In most cases that distinction is nit-picky. It can be perfectly reasonable for the language to throw up its hands, shout "undefined behavior", and just assume that whatever random uncontrolled thing happens won't be too terrible, assuming whatever your program does isn't too important. But for security-critical applications it's a really stinking important distinction, because the range of possible behaviors found in the "undefined" category includes things like Heartbleed.

Re:How to zero a buffer by pcwalton on Friday September 05, 2014 @02:53AM (#8272619)
If your compiler couldn't perform dead store elimination on memory (remember, memory includes allocas), then you'd lose most of the benefits of performing standard SSA form optimizations after SROA has happened. Essentially you'd kill scalar replacement of aggregates, which is a critical optimization. It's very important for performance that it allowed to happen.
Re:How to zero a buffer by bunderbunder on Friday September 05, 2014 @03:04PM (#8275684)
Note that I'm not saying that dead store elimination is the problem. I'm saying that dead store elimination in combination with other language features is a problem. Dead store elimination is not unique to C. But those other language features are. Since I'm complaining about C in particular, I submit that the bit that I'm most worried about isn't the stuff that every language does.

That said, I realize that allowing data that's hypothetically disappeared forever into the free() black hole to come back into the universe through white holes such as malloc() and buf[buf_length] aren't the only reasons why you'd want to make for sure that you can clear out unused memory. Which is why it would be nice if the C spec also included some way to securely clear up memory that the compiler isn't allowed to defeat. No, an optional feature in a spec that's only 3 years old and mostly not supported isn't good enough. If it isn't ubiquitous it's not a whole lot more useful than any of the platform- and architecture-specific fixes that already exist.

Re:How to zero a buffer by ibisum on Friday September 05, 2014 @02:58AM (#8272633)
You want your compiler, and execution environment, to support it. In C's case, the compiler can do a lot of work in this department - but so can most modern OS's in the real-world, provide adequate protection:

    sbuf = mmap(..,..,MAP_PRIVATE|MAP_ANON); // &etc.
Re:How to zero a buffer by ygra on Friday September 05, 2014 @09:35AM (#8273762)
I'm not sure how this depends on the language, per se. Basically you want very special behaviour here: Allocate a piece of memory, preferrably so that it doesn't end up accidentally in permanent storage and later clear it and deallocate it again. C gives you no such facilities to do so, but so do very few other languages (if any). The correct course here would rather be to ask the OS to do that for you. You can tell the memory allocator to never page out the block you get. Every OS has a syscall to zero memory that isn't subject to compiler optimisations.

Honestly, in my eyes, this is a place where the language is specified in a way that it cannot ever guarantee what you're trying to achieve and in that case you're best off not relying on the language, but on other things that can make such guarantees.

Re:How to zero a buffer by maxlybbert on Friday September 05, 2014 @12:40AM (#8272342)
C may have pitfalls for "these kinds of applications," but it has some strengths that other languages don't. Since C gives the programmer significant control over memory allocation, it's possible to avoid various kinds of timing attacks related to cache misses (possible is not the same as easy). Many languages don't give the programmer the necessary tools to do that.
Re:How to zero a buffer by dllthomas on Friday September 05, 2014 @12:49AM (#8272360)
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 <other existing language> 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 C would have been were it not for those choices", which seems an easy case to make.
Re:How to zero a buffer by maxlybbert on Friday September 05, 2014 @04:32AM (#8272826)
The funny thing to me is that the standard crypto packages for other languages nearly always end up calling C code.
Re:How to zero a buffer by dllthomas on Friday September 05, 2014 @12:11PM (#8274674)
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 by maxlybbert on Friday September 05, 2014 @01:52PM (#8275218)
True.
Re:How to zero a buffer by PhasmaFelis on Friday September 05, 2014 @06:13AM (#8273115)
C/C++ are like Formula 1 racing cars: indispensable if you need to go really, really fast; wildly impractical in all other situations.
Re:How to zero a buffer by exDM69 on Saturday September 06, 2014 @08:10AM (#8278135)
> C/C++ are like Formula 1 racing cars ...

I can't agree with this comparison at all. It may be true if speed is what you want but that's not the only reason.

C (and to a lesser extent, C++) are indispensable in lots of situations where you're working close to the metal. There are very few viable alternatives when working with kernel space code, micro controllers or embedded applications as well as crypto primitives.

Rust is perhaps the only language that can be used instead of C and C++ in these applications.

I'd liken C more to a heavy duty vehicle, something that most people never need but there's no replacement for the tasks it is intended for.