Live data from Hacker News

Stop Memsetting Structures

anmolsarma.in

201–210 of 277 posts

Re: Stop Memsetting Structures

#201

Earlier quoted context omitted.

If you're either using via either assigning or reading the value that is stored in the padded area of a class or struct you are in undefined behavior, any version of the standard you choose. So, care to explain the downvotes?

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

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

Re: Stop Memsetting Structures

#202

Earlier quoted context omitted.

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

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

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.

Re: Stop Memsetting Structures

#203
post #47
post #41

Earlier quoted context omitted.

Please explain how you send a struct over the network without UB and leaking the padding.

By knowing its exact size with sizeof(), and using that and a cast to uint8_t* to both bzero() it out before use and memcpy()ing it when sending it. Unless the C standard says that the compiler may change the padding bytes of the existing storage?

Obligatory pet peeve note: sizeof is a unary operator whose argument is written in parentheses if it is the name of a type. It is not a function.

Re: Stop Memsetting Structures

#204
post #45

Earlier quoted context omitted.

I am aware of the fact that unitilized padding can have nasty side effects: https://lwn.net/Articles/417989/ But yeah, I should have mentioned the caveats too. I will update the post once I'm back at my computer.

I'm confused what I'm supposed to look for in that article (do you mean you were the author?) but anyway -- I feel like calling this merely a "caveat" gives the wrong impression? It seems a bit like telling people to mix bleach with vinegar and then saying "Oops, sorry, I did know that it produces chlorine! I forgot to mention that caveat." The caveat isn't just a side note for the margins, it's a critical reason why…

If the author is only going to add "caveat", then that sounds like word games and being unwilling to admit that the blog post's advice is wrong (for the security risks and other reasons pointed out here in the comments)

Re: Stop Memsetting Structures

#205

Earlier quoted context omitted.

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

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.

Re: Stop Memsetting Structures

#206

Earlier quoted context omitted.

Consider the lorawan spec which was written in the last 5 years. The stack is designed to be implemented in software on small 32 bit microcontrollers which are _all_ little endian. And it's big endians. The people that wrote that spec knew that and went with big endian anyways. Also I work with people that do network hardware. They can't care less about little or big endian. Makes no difference to them.

Someone needs to pick one or the other: you can't have it both ways.

Yeah they are picking the side everyone else abandoned 25 years ago.

Re: Stop Memsetting Structures

#207

Earlier quoted context omitted.

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.

Re: Stop Memsetting Structures

#208

Earlier quoted context omitted.

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

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

Re: Stop Memsetting Structures

#209

Earlier quoted context omitted.

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

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

Re: Stop Memsetting Structures

#210
post #105

Earlier quoted context omitted.

> Code external to yours may make assumptions about what lies in your padding, either by doing memcmp's, or adding new fields in a later version of the struct and intending it to be ABI compatible between modules. The content of the padding between members can arbitrarily change during assignments of members, so code relying on the content of it is broken anyways. In the case of an extended struct both methods are eq…

If you use: sizeof(struct_instance) the compiler will automatically update the size passed to memcpy. (I like passing the instance to sizeof and not the type, just in case the type of the thing being copied changes in a future version of the code.)

That is exactly what I said:

> ...if you don't recompile your module with the updated definition of the struct...

And once you recompiled, the C99 version with the pretty initializer is fixed as well, so there is no advantage in using memset regarding this.

Post reply on HN