5 ms·
I'm not sure the NULL pointer access being allowed point is valid. The C standard allows for the NULL pointer to be numerically any value, not just 0, and on s
by nickcw 8y ago
I'm not sure the NULL pointer access being allowed point is valid.
The C standard allows for the NULL pointer to be numerically any value, not just 0, and on some architectures in isn't 0. So I would hope C compilers targeting wasm would just use a different value for the NULL pointer, eg 0x8000000000000000 not 0.
Whether they actually do or not I don't know, but it isn't an architectural failing of wasm.
- deleted 8y ago[deleted]
- hpbd 8y agoYou are right, but changing the starting address of the WebAssembly memory map to something else (like 0x8000) would've been easier.
- kllrnohj 8y agoYou can have a valid pointer to 0x00, but you only see it on microcontrollers and it doesn't really exist in any context WASM is being discussed. The author's argument that this is a mistake is true. WASM should almost certainly have had some arbitrary offset like 0x1000 just due to the extreme commonality of null pointer derefs, and changing NULL to something else won't come close to solving that problem. You still have pointer derefs of fields in structs that were calloc'd or memset(0)'d. Compiler can't magically swap out the writes-to-zero there with whatever NULL should be instead.
- saurik 8y agoInstead of providing some one-off special case for addresses close to 0, they could have what actual computers actually have: a way to mark regions of memory as unusable (which the WebAssembly code could then do), which would also provide help with other issues like stack overflows.
- kllrnohj 8y agoWhat computers actually have is literally just an arbitrary offset to catch null pointers. They then also have ways to mark pages as read-only and such, but they don't burn a bunch of pages on this for NULL pointer catching. They simply just don't map anything before the program offset.
- saurik 8y agoI don't understand what you mean by "arbitrary offset", but the way people usually implement both "crash on null dereference" and stack guards is the same: they not only don't map anything at those addresses but they map reservations at those addresses that are neither readable nor writable (and so usually never commit to backing memory). On 32-bit macOS Mach-O executables you can even see the reservation as it is so explicit: there is literally just a "segment" defined in the executable, with no contents, mapped to the pages at address 0 that can't be accessed. If you leave it out of the executable, the page might get used (such as by mmap, maybe due to malloc): it is entirely optional, but happens to be a default from the C compiler/linker. As we almost always want this, often operating systems now do this for you by default without requiring the programmer to instruct it, but that is just a different programmer instructing the computer, still using the same virtual memory paging system: there is no magic property of the computer that is making low addresses inaccessible, they are just using the mechanism for mapping virtual address space with different permissions (and again: this same mechanism is used to prevent null dereferences and protect against stack overflows, both of which are semi-arbitrary flaws in C that the computer has no business hardcoding).
- azakai 8y agoIt's true that in theory a NULL pointer could be 0xffffffff or such, and that would prevent some of the problems the article mentions. However, that would only help when you assign NULL to a pointer explicitly. The problem is that in practice NULL pointers are often caused by other things, like thinking that zero-initialized memory contains a pointer - in fact, this is even more common in wasm than natively, since wasm guarantees memory and stack are initialized to zero. This is serious enough an issue that for debugging purposes emscripten has a SAFE_HEAP mode which will check for NULL pointers on every access. We'd still need that to look for 0 even if the compiler considered NULL to be something other than 0.
- int_19h 8y ago> The problem is that in practice NULL pointers are often caused by other things, like thinking that zero-initialized memory contains a pointer Which, to be clear, is not a valid assumption wrt portable C or C++.
- spc476 8y agoWhile C may not mandate zero-initialized pointer is NULL, POSIX does.
- devit 8y agoSetting NULL or nullptr to any value other than 0 is highly likely to break most complex C/C++ codebases.
- cyphar 8y agoEven simple codebases that do if (!p) Anywhere would immediately cause problems.
- saagarjha 8y agoThis is legal in C, even if the representation for a null pointer is not actually "all zero bits" internally. The null pointer is defined to compare equal to 0, which is the contrapositive of what your test is doing.
- sigjuice 8y agoWhat part of the C standard allows for the NULL pointer to be numerically any value? I am looking at n1256.pdf, but I can't seem to find the relevant text.
- int_19h 8y agoIt's not spelled out explicitly. Rather, what's missing from the standard is the requirement that a null pointer is all-bits-zero, or that reinterpret_cast'ing it to an integer type produces a zero (note that even these two are actually separate). This is deliberate - there have been platforms in the past where null pointer had a non-zero bit pattern for largely the same reasons (null address was valid and useful).
- sigjuice 8y agon1256.pdf, Section 6.3.2.3 Pointers, says "constant expression with the value 0". An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. I don't think this definition excludes platforms that use non-zero bit patterns. A constant 0 in C code should get converted to the appropriate (possibly non-zero) bit-pattern for the platform. Also, my understanding is that whether the platform has useful things at address 0 falls in the category of "implementation defined".
- saagarjha 8y ago> I don't think this definition excludes platforms that use non-zero bit patterns. It doesn't; the comment above yours is saying the same thing as you are.
- int_19h 8y ago> Also, my understanding is that whether the platform has useful things at address 0 falls in the category of "implementation defined". If address zero is a null pointer, then IIRC no allocated object, whether static, automatic or heap, can have that address - i.e pointers to them must always compare unequal to nullptr. If null pointer is something other than address zero, then it's just a regular address, and can have anything - it's not even "implementation defined", not anymore so than saying that e.g. 0x12345678 is a valid object address on x86.