FS#15556 - [kernel26] CVE-2009-1987 null pointer dereference vulnerability in tun_chr_poll()
Attached to Project:
Arch Linux
Opened by Kerin Millar (kerframil) - Saturday, 18 July 2009, 02:59 GMT
Last edited by Roman Kyrylych (Romashka) - Wednesday, 22 July 2009, 18:21 GMT
Opened by Kerin Millar (kerframil) - Saturday, 18 July 2009, 02:59 GMT
Last edited by Roman Kyrylych (Romashka) - Wednesday, 22 July 2009, 18:21 GMT
|
Details
>=2.6.30 is affected by a null pointer dereference
vulnerability introduced by the following commit:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=33dccbb050bbe35b88ca8cf1228dcf3e4d4b3554 This allows for local root privilege escalation, as demonstrated by Brad Spengler's cheddar_bay exploit: http://grsecurity.net/~spender/cheddar_bay.tgz Here's the upstream commit which rectifies the problem: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3c8a9c63d5fd738c261bd0ceece04d9c8357ca13 And here are some links which provide additional information: http://isc.sans.org/diary.html?storyid=6820 http://lists.immunitysec.com/pipermail/dailydave/2009-July/005810.html http://www.youtube.com/watch?v=UdkpJ13e6Z0 https://bugzilla.redhat.com/show_bug.cgi?id=512284 |
This task depends upon
Closed by Roman Kyrylych (Romashka)
Wednesday, 22 July 2009, 18:21 GMT
Reason for closing: Fixed
Additional comments about closing: Linux-2.6.30.2 is now in [core]
Wednesday, 22 July 2009, 18:21 GMT
Reason for closing: Fixed
Additional comments about closing: Linux-2.6.30.2 is now in [core]
http://patchwork.kernel.org/patch/36060/
"Critical" is for extreme cases, like something that gets an HDD with all your data burned, or remotely take over your system.
> That's why the vulnerability is interesting and new: because when compiling without
> -fno-delete-null-pointer-checks, gcc removes the NULL check, assuming that anyway
> dereferencing to NULL would cause an exception and be handled accordingly
This is false. The reason the check is removed is because the deferencing has already occurred at that point.
As it stands, sk is initialised to tun->sk and only thereafter is tun compared to NULL. The fact that the null pointer check occurs after the assignment in the original code - which involves dereferencing the pointer - is what makes gcc think it's OK to optimise away said check (as it makes the arguably reasonable assumption that once it has been dereferenced it is not NULL and so further checks are unnecessary). As I have already stated, this bad code was introduced in commit 33dccbb050bbe35b88ca8cf1228dcf3e4d4b3554. Look, it's even confirmed by the cheddar_bay code itself (the comment in exploit.c):
"The commit that introduced the vulnerability (Feb 6th)
http://mirror.celinuxforum.org/gitstat/commit-detail.php?commit=33dccbb050bbe35b88ca8cf1228dcf3e4d4b3554
Though it was committed before the release of the 2.6.29 kernel, it
did not (thankfully) make it into the 2.6.29 kernel. It first
appeared in 2.6.30."
Irrespective of how gcc behaves, if the pointer is potentially NULL, the check should occur before it's dereferenced; that it does not is a bona fide bug and _this_ is what I am talking about. And so, commit 3c8a9c63d5fd738c261bd0ceece04d9c8357ca13 ensures the the pointer is not dereferenced until after the check thus resolving the issue correctly:
36 - struct sock *sk = tun->sk;
37 + struct sock *sk;
38 unsigned int mask = 0;
39
40 if (!tun)
41 return POLLERR;
42
43 + sk = tun->sk;
The previous behaviour is so obviously wrong, I don't understand how there can be any confusion regarding it.
The aforementioned patch has been queued for 2.6.30.2. Meanwhile, 2.6.30 and 2.6.30.1 are potentially vulnerable. If you want to be certain that your userbase is protected prior to the arrival of 2.6.30.2, the patch should be applied.
PS: Jonathan Corbet touches upon a particularly interesting facet of the matter here: http://lwn.net/Articles/341959/