There is no compiler bug here. As paragraph 6.5.3.2.4 of the C99 standard
says, "If an invalid value has been assigned to the pointer, the behavior
of the unary * operator is undefined." Undefined here means "behavior,
upon use of a nonportable or erroneous program construct or of erroneous
data, for which this International Standard imposes no requirements"
(paragraph 3.4.3.1). Judging by the standard it seems to be legal to
optimize the null pointer guard away, as it has no side-effects in the
case of a valid pointer value. In the case of this kernel bug
this "undefined behavior" unfortunately makes the bug exploitable which
it presumably would not have been had the guard not been optimized away.
Posted Jul 18, 2009 14:31 UTC (Sat) by xoddam (subscriber, #2322)
[Link]
Uh, the zero pointer value is not an 'invalid value' if there's readable memory at address zero. The standard declines to define correct behavior for 'invalid' pointers because there are many ways for a pointer to be 'invalid' in some sense or another and several ways for an implementation to handle them (return garbage, return zero, deliver a signal, halt)
The exploit works because in this case, null is NOT an invalid value, but the compiled code behaves as though it is (and as though the compiler knows how the dereferencing of an invalid value will be handled ... which it doesn't). So yes, it's a compiler bug.
Yes, this is a compiler bug.
Posted Jul 18, 2009 17:20 UTC (Sat) by xilun (subscriber, #50638)
[Link]
So if you move the compiler out of the C standard respecting equation then this is a compiler bug? Makes absolutely no sense. This is a C compiler, not a "I would prefer it do that" compiler. You should better define your own langage where dereferencing a NULL pointer is NOT undefined.
The platform is defined by the compiler and the runtime. The compiler definitely has the right to consider that dereferencing a NULL pointer is something that is always undefined, because, well, the standard precisely says that. There is no story of mapping or not mapping pages at this point : NULL pointer dereferencing an undefined behavior is, and NULL pointer dereferencing an undefined behavior stays. A NULL pointer has been dereferenced, the behavior is undefined (and it's not very surprising that an undefined behavior as per a standard can be an exploitable security hole). This is as simple as that.
The bug also is in allowing to map address 0, which can't be a sane way to serve a sane purpose.
Yes, this is a compiler bug.
Posted Jul 18, 2009 22:53 UTC (Sat) by mstefani (subscriber, #31644)
[Link]
> The bug also is in allowing to map address 0, which can't be a sane way to serve a sane purpose.
If you happen to need to run a DOS program in Wine or sometimes even a Win32 application that still uses some DOS calls then you need access to the memory at 0x00000000. http://wiki.winehq.org/PreloaderPageZeroProblem
Yes, this is a compiler bug.
Posted Jul 19, 2009 0:07 UTC (Sun) by xilun (subscriber, #50638)
[Link]
I could argue that supporting program written for broken systems is not a sane purpose ;)
Yes, this is a compiler bug.
Posted Jul 19, 2009 8:00 UTC (Sun) by packet (guest, #5202)
[Link]
Footnote 84 of the C99 standard clearly says so: "Among the invalid
values for dereferencing a pointer by the unary * operator are a null
pointer, an address inappropriately aligned for the type of object
pointed to, and the address of an object after the end of its lifetime."
Before that sentence, only one exception is mentioned: (&*E == E) is
true, even in the case of a null pointer. IMHO the compiler can legally
do just about anything in the case of dereferencing a null pointer. The
lowest addressable object in C lives at address 1*sizeof(object). If null
was allowed as a valid pointer, there would be no pointer value to check
for invalid pointers. Sadly, this means that at least one byte (in the C
sense: a byte is a char) of the address space cannot be legally addressed
in C. If you consider this a bug, it's a language bug, but not a compiler
bug.