Hello,

>> The superfluous NULL check here is preventing the elimination of the
>> store. In my opinion we should optimize this based on the assumption
>> that a pointer can't be NULL after a load/store to it. GCC does this
>> and got some flak because it turned a crash into a security problem
>> in the Linux kernel (-fno-delete-null-pointer-checks was introduced
>> as a remedy). I'm not sure how to best implement that with our
>> current VRP infrastructure.
> 
> Interesting. Do you mean that the kernel will not internally fault if it 
> stores to some place near 0x0? Or was the offset so large that it was going 
> someplace valid?

The former. From the paper "Undefined Behavior: What Happened to My Code"
(<pdos.csail.mit.edu/papers/ub:apsys12.pdf>):

| unsigned int
| tun_chr_poll(struct file *file, poll_table * wait) {
|   struct tun_file *tfile = file->private_data;
|   struct tun_struct *tun = __tun_get(tfile);
|   struct sock *sk = tun->sk;
|   if (!tun)
|     return POLLERR;
|   ...
| }
|
| Figure 6: An invalid null pointer check due to null pointer dereference, in
| drivers/net/tun.c of the Linux kernel, which uses GCC’s 
-fno-delete-null-pointer-checks
| to prevent such checks from being removed.
|
| Figure 6 shows an example from the Linux kernel. The code dereferences tun
| via tun->sk, and only afterward does it validate that tun is non-null. Given
| a null tun, it was expected that this null-check-after-dereference bug would
| either cause a kernel oops as a result of the tun->sk dereference, or return 
an
| error code due to the null pointer check (e.g., when address 0 is mapped). 
Neither
| was considered a serious vulnerability.
|
| However, an unexpected optimization makes this bug exploitable. When GCC sees
| the dereference, it assumes that tun is non-null, and removes the “redundant”
| null pointer check. An attacker can then continue to run the rest of the 
function
| with tun pointing to address 0, leading to privilege escalation [9]. The Linux
| kernel started using GCC’s -fno-delete-null-pointer-checks to disable such
| optimizations.

> In any case, I guess that we should probably do the same.

I agree. This is undefined behavior clang should exploit for optimizations.


Jonathan


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to