Hacker News new | ask | show | jobs
by jcr1488 2607 days ago
If you pass partially uninitialized objects (including padding) between kernel space and user space, there's a chance that the (less privileged) user space code can recover information it shouldn't be able to see, regardless of what the spec says about undefined behaviour. Such information may include secrets that previously occupied the memory where a new, unrelated struct now resides. The same can also apply to passing objects between different machines.

All "undefined behaviour" means is that the spec can no longer guarantee anything about the execution of a program once a constraint is violated. It doesn't say anything about the practicality of actually doing it on any given implementation.

FWIW I didn't downvote you, but your reasoning about undefined behaviour seems overly simplistic. It should never be used to explain away security concerns.

1 comments

It shouldn't be used to explain away security concerns, but it shouldn't be used to overstate security fixes either.

You can memset to 0, and on your compiler it might be secure, but it's not enough to keep your security guaranteed against future compilers.

There's a reason functions like SecureZeroMemory exist. In a similar situation, you try to prevent leaking secure secrets by zeroing memory before releasing it. But the compiler sees you never use the variable again, and optimizes away the zeroing.

The message to take away is not "be less paranoid". It's "be more paranoid".

Right, but I didn't make a case that memset() is any more secure, did I? The parent comment was talking about undefined behaviour as if it's some kind of universal get-out clause.
Your last paragraph strongly implies that hermitdev was using undefined behavior to "explain away" security concerns.

But the problem is that the security concerns and fixes are all undefined here.

So the initial comment is still very right. If you're relying on the padding to be anything in particular, you're in trouble.

> But the problem is that the security concerns and fixes are all undefined here.

No one in this sub-thread has mentioned (or implied) any "fix". You appear to be putting words in my mouth.

> So the initial comment is still very right.

Of course it's right, but it's also misleading when read in the context of the parent comment.

> If you're relying on the padding to be anything in particular, you're in trouble.

No shit.

> No one in this sub-thread has mentioned (or implied) any "fix". You appear to be putting words in my mouth.

I'm talking about the comments hermitdev was replying to that were treating memset as a 'fix'.

And 'fix' is shorthand for the opposite of "open[ing] you up to all kinds of info leaks". I don't think that's putting words in anyone's mouth.

I guess we are misunderstanding each other's point. I just found hermitdev's comment to be misleading (despite being correct), but perhaps it's just my reading of it.

To be fair though, memset() usually IS a fix. As mentioned by the kernel memzero_explicit() docs:

> usually using memset is just fine (!)

-- https://www.kernel.org/doc/htmldocs/kernel-api/API-memzero-e...

A conforming C compiler can't just remove memset() as it pleases. The case that most often requires memzero_explicit() is when zeroing an object after destruction, because the compiler thinks it can statically determine that it's a dead store. It very rarely happens that a compiler elides a memset() used for initialization.

I'm not sure why you seem to think that memset() can just be dropped at will for no reason whatsoever or that it's somehow always undefined behaviour.