On Thursday, 27 July 2017 at 13:45:21 UTC, ag0aep6g wrote:
On 07/27/2017 03:24 PM, Moritz Maxeiner wrote:
--- null.d ---
version (linux):

import core.stdc.stdio : FILE;
import core.sys.linux.sys.mman;

extern (C) @safe int fgetc(FILE* stream);

void mmapNull()
{
void* mmapNull = mmap(null, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE, -1, 0); assert (mmapNull == null, "Do `echo 0 > /proc/sys/vm/mmap_min_addr` as root");
     *(cast (char*) null) = 'D';
}

void nullDeref() @safe
{
     fgetc(null);
}

void main(string[] args)
{
     mmapNull();
     nullDeref();
}
---

For some fun on Linux, try out
# echo 0 > /proc/sys/vm/mmap_min_addr
$ rdmd null.d

The gist of this is that Linux can be configured so that null can be a valid pointer. Right?

In summation, yes. To be technical about it:
- Linux can be configured so that the bottom page of a process' virtual address space is not protected from being mapped to valid memory (by default, `mmap_min_addr` is 4096, i.e. the bottom page can't be mapped) - C's `NULL` is in pretty much all implementations (not the C spec) defined as the value `0`, which corresponds to the virtual address `0` in a process, i.e. lies in the bottom page of the process' virtual address space - The null dereference segmentation fault on Linux stems from the fact that the bottom page (which `NULL` maps to) isn't mapped to valid memory - If you map the bottom page of a process' virtual address space to valid memory, than accessing it doesn't create a segmentation fault


That seems pretty bad for @safe at large, not only when C functions are involved.

Yes:
- In C land, since derefencing `NULL` is UB by definition, this is perfectly valid behaviour - In D lang, because we require `null` dereferences to crash, we break @safe with it

Reply via email to