== An example of optimizing C in the face of undefined behavior In [[my entry about my understanding of modern C undefined behavior UndefinedCNutshell]] I alluded to how modern C created a security vulnerability in the Linux kernel because of variable initialization. Today I feel like showing you roughly the code involved and explaining this, rather than alluding to it indirectly. We'll start with perfectly functional code: .pn prewrap on > int func(struct foo *arg) > { > struct bar *p; > > if (arg == NULL) > return -EINVAL; > p = arg->f_p; > > [.....] This works right. Then someone comes along and fiddles with the code a bit: > int func(struct foo *arg) > { > struct bar *p = arg->f_p; > > if (arg == NULL) > return -EINVAL; > > [....] In the Linux kernel dereferencing a NULL pointer does not immediately segfault so this code is (sort of) okay as written; if _arg_ is _NULL_ we will read some bit of low memory and then return. Then the optimizing compiler shows up. The compiler knows that no conforming C program can ever dereference a null pointer; to do so is undefined behavior. Since the code dereferences _arg_ without checking for _NULL_, the compiler is entitled to assume that _arg_ is never _NULL_. This makes the _if_'s expression into a constant value (it must always be false) and the whole _if_ can then be eliminated as dead code. Now this function will continue on even if _arg_ is _NULL_ and in the process use whatever it fished out of memory as _p_ ([[this enables the actual exploit ../linux/KernelPageZeroProblem]]). This is of course bad code (since you should never dereference potentially _NULL_ pointers). But it would not naturally be fatal; it took a C compiler optimizing code to make it that. (The exact code is used as an example [[here https://www.securecoding.cert.org/confluence/display/seccode/EXP34-C.+Do+not+dereference+null+pointers]] if you want to read it. It is somewhat more intricate than my version but not much so.)