@safe code should prevent null dereferences

Elronnd elronnd at elronnd.net
Mon Nov 23 22:59:05 UTC 2020

I've been meaning to make a post about this for a while, and the 
other thread on the topic reminded me.

D does not attempt to prevent null pointer dereferences in @safe 
code.  This is predicated on the assumption that dereferencing a 
null pointer will always cause a fault, and as such does not 
represent a safety concern.  This assumption is wrong.

There was a somewhat famous bug in the linux kernel caused by the 
compiler assuming that a null dereference would never happen.  
The code looked something like this (see [1] for more details):

struct mystruct {
	int x;
void function(struct mystruct *m) {
	// (1)
	int t = m->x;

	// since 'm' was already dereferenced at (1), the compiler 
	// that there is no way for 'm' to be null here.  So it removes
	// the check and unconditionally executes 'stuff'.
	if (m) {

Of course, the zero page was mapped as readable in kernel space.  
So if you passed NULL into the function, bad things would happen.

The bug was fixed, but linux is also now compiled with a special 
compiler flag telling the compiler to assume that null pointers 
may be accessible[2].  As noted in the commit message, that bug 
was not an isolated one, and there have been other cases when 
null pointer checks were incorrectly removed.

For d, the situation is even worse than in c.  In c, it is 
undefined behaviour to dereference any invalid pointer; but in d 
null pointers are singled out and it is only unspecified what 
happens when they are accessed[3].  The specification is clearly 
aware that null pointers are accessible, but no allowance for 
this is made in the sections on @safe[4][5].  It would be very 
easy to cause memory corruption or leak information through a 
null pointer access.

Most d code runs in userspace, but it clearly has ring0 
aspirations.  There was a talk[6] at dconf last year about using 
d in the linux kernel.  There have also been a few experimental 
kernels implemented in pure d, most notably powernex[7]; and 
there has been interest in getting d to run on microcontrollers 
(this is the only really legitimate use for betterc).

If safeD wants to be useful for kernels, it needs a way to 
prevent null pointer dereferences.



1. https://lwn.net/Articles/342330/


3. https://dlang.org/spec/arrays.html#pointers

4. https://dlang.org/spec/memory-safe-d.html

5. https://dlang.org/spec/function.html#function-safety

6. https://www.youtube.com/watch?v=weRSwbZtKu0

7. https://github.com/PowerNex/PowerNex

More information about the Digitalmars-d mailing list