@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
assumes
// that there is no way for 'm' to be null here. So it removes
// the check and unconditionally executes 'stuff'.
if (m) {
stuff;
}
}
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.
-----------------------------------------------------------------------
References:
1. https://lwn.net/Articles/342330/
2.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a3ca86aea507
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