On Thursday, 22 September 2016 at 12:08:19 UTC, Steven Schveighoffer wrote:
On 9/20/16 12:45 PM, cym13 wrote:
On Tuesday, 20 September 2016 at 14:00:00 UTC, Steven Schveighoffer wrote:


Dereferencing a null pointer is perfectly safe in user space (where you can't map the zero page). Indexing a null pointer is not. In this case, we are indexing a null pointer, so there is the potential for
abuse, but very very small.

Note that not all operating systems disallow mapping the zero page (although they admitedly should). And yes the potential for abuse is
small, I've just getting annoyed at dangerous generalities.

We can simply avoid supporting such OSes, I don't think we lose much! But thanks for pointing this out, I didn't know that.

We lose at least all linux kernels before 2.6.23... although it sounds reasonnable it's a choice that's better made knowingly ;)

In that specific case I don't think it should be treated as a security issue in the general case although it could become one if used in an
unfavorable environment.

I had an interesting thought, and this is actually a @safe issue (I'll file an issue request). If you have a potentially large enough struct, then accessing items in that struct has the potential to go beyond the unmapped memory.

However, in MOST cases, the compiler knows the offset being used (especially if accessing specific members). In some cases it doesn't. But one thing the compiler can do (at least in @safe code) is:

1. If the index is known at compile time to go beyond one page (or beyond the known OS limit for unmapped pages), do a null pointer check first, and abort with segfault if possible. As simple as loading the byte/word at the front of the struct. You also only have to do this once if the struct pointer does not move. 2. If the index is not known until runtime (for instance, indexing a static array in a struct), then check for null pointer before dereferencing conservatively.

This would make code that is very common (i.e. small struct size, or accessing front members of the struct) just use the hardware features to prevent access. Code that is rare (accessing members beyond one page of size) can be instrumented to ensure no exploits are possible.

-Steve

This is very interesting, I'm sure there are ways to expand on this idea further (but even just that would be a real improvement). One thing is that although I don't see people willingly creating such a big struct not all D code is written by humans and with some mixin or template help it's a possibility. I'd love to see some protection where the compiler can work it out.

Reply via email to