Live data from Hacker News

How to zero a buffer

daemonology.net

71–80 of 216 posts

Re: How to zero a buffer

#71

Earlier quoted context omitted.

To clarify: the strategy in the post doesn't actually work (or at least, is not guaranteed to work in every conforming implementation): the "volatile" only applies to the read of the function pointer, not to the execution of the function in question. You don't even need to assume some sort of crazy evil compiler to have to worry about this - speculative inlining of function pointers guarded by a safety check is somet…

The first comment there (by Anonymous) claims that the final technique can also be optimized: (memset_ptr)(p, 0, len); > can be replaced by: if (memset_ptr == memset) { memset(p, 0, len); } else { memset_ptr(p, 0, len); } > Which in turn can be optimized using the other tricks noticed above into: if (memset_ptr != memset) { memset_ptr(p, 0, len); } I'm no expert, but this seems like a believable defeat of the techniq…

That's not quite right since it's now reading memset_ptr twice, but the concept does seem to be right -- the volatile pointer must be read but the standard doesn't require that the function is invoked.

Re: How to zero a buffer

#72
post #44

When I allocate the key on the heap, the memset is carried (heavily optimized and inlined). When I allocate key on the stack, it disappears. Using gcc -03: #include void doSecure(void) { /*char key[32];*/ char *key = (char*) malloc(sizeof(char)*32); memset(key,sizeof(char),32); } int main(void) { doSecure(); return 0; } -- key on stack main: .LFB13: .cfi_startproc xorl %eax, %eax ret .cfi_endproc -- key on heap main:…

A more realistic idiom is memset followed by free. The free provides a solid hint to the compiler that the object is dead without relying on escape analysis.

Naturally, however adding free made no difference in this case. I guess if your dealing with a raw pointer rather than an array type, gcc cant be sure what memory you intend to erase.

Re: How to zero a buffer

#73

Earlier quoted context omitted.

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.

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.

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

#74

Earlier quoted context omitted.

I think the best answer there is "it depends". Facebook has an open job posting which states that "Our goal over the next few years is for the Linux kernel network stack to rival or exceed that of FreeBSD" [1], so clearly there's at least one place in Facebook where Linux does not provide the best performance... [1] https://www.facebook.com/careers/department?req=a0IA000000Cz...

I wonder when that was posted. Linux networking has improved massively since the 2.6 days, and continues to get better. It's still not FreeBSD, but the difference is pretty small these days.

Within the past couple of months, I believe. Speculation at the time was that this was fallout from Facebook devops trying to port Whatsapp to run on Facebook's systems.

Re: How to zero a buffer

#76

Why wouldn't you make key volatile? Shouldn't that solve all the problems? Or is it because it would be to slow because the compiler can't do that many optimizations in the rest of the function any more?

Yes, making key volatile would force the zeroing to happen; and yes, you don't want to do that because it would absolutely kill your code performance.

Can't you just cast it to a `volatile uint8_t *` at some later point when you need to ensure that we've zeroed the memory?

Re: How to zero a buffer

#77
post #73

Earlier quoted context omitted.

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.

Many languages zero every allocation unless they can prove that you immediately write over that memory without reading it.

[deleted]

Re: How to zero a buffer

#78
post #73

Earlier quoted context omitted.

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.

Many languages zero every allocation unless they can prove that you immediately write over that memory without reading it.

Which does nothing for memory which has been freed but not reallocated.

Re: How to zero a buffer

#79
post #73

Earlier quoted context omitted.

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.

Many languages zero every allocation unless they can prove that you immediately write over that memory without reading it.

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

#80

Earlier quoted context omitted.

Yes, making key volatile would force the zeroing to happen; and yes, you don't want to do that because it would absolutely kill your code performance.

Can't you just cast it to a `volatile uint8_t *` at some later point when you need to ensure that we've zeroed the memory?

That's discussed in the article. Volatile ultimately applies to the storage, so a sufficiently smart compiler may be able to deduce that you're lying to it with the cast and elide the write.
Post reply on HN