]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Netfilter: do_add_counters race, possible oops or info leak (CVE-2006-0039)
authorChris Wright <chrisw@sous-sol.org>
Tue, 16 May 2006 19:07:20 +0000 (12:07 -0700)
committerChris Wright <chrisw@sous-sol.org>
Sat, 20 May 2006 22:00:31 +0000 (15:00 -0700)
Solar Designer found a race condition in do_add_counters(). The beginning
of paddc is supposed to be the same as tmp which was sanity-checked
above, but it might not be the same in reality. In case the integer
overflow and/or the race condition are triggered, paddc->num_counters
might not match the allocation size for paddc. If the check below
(t->private->number != paddc->num_counters) nevertheless passes (perhaps
this requires the race condition to be triggered), IPT_ENTRY_ITERATE()
would read kernel memory beyond the allocation size, potentially causing
an oops or leaking sensitive data (e.g., passwords from host system or
from another VPS) via counter increments.  This requires CAP_NET_ADMIN.

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=191698

Cc: Solar Designer <solar@openwall.com>
Cc: Kirill Korotaev <dev@sw.ru>
Cc: Patrick McHardy <kaber@trash.net>
(chrisw: rebase of Kirill's patch to 2.6.16.16)
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c

index 7d7ab94a7a2e73abef1f804174aed3c94abf86ac..12bfc257743454c2e43e4fdaaff27d9b20dc51ab 100644 (file)
@@ -941,7 +941,7 @@ static int do_add_counters(void __user *user, unsigned int len)
 
        write_lock_bh(&t->lock);
        private = t->private;
-       if (private->number != paddc->num_counters) {
+       if (private->number != tmp.num_counters) {
                ret = -EINVAL;
                goto unlock_up_free;
        }
index 16f47c675fefd8304d86174f6d4beeebdec6539b..735d5ff5061b2a8d43c3800231f2d3b745377c01 100644 (file)
@@ -1063,7 +1063,7 @@ do_add_counters(void __user *user, unsigned int len)
 
        write_lock_bh(&t->lock);
        private = t->private;
-       if (private->number != paddc->num_counters) {
+       if (private->number != tmp.num_counters) {
                ret = -EINVAL;
                goto unlock_up_free;
        }
index 74ff56c322f47ee45b3b873e4672d0bc9c13511a..dd6ad4228aa6301f980392d0662b7b88fba0529e 100644 (file)
@@ -1120,7 +1120,7 @@ do_add_counters(void __user *user, unsigned int len)
 
        write_lock_bh(&t->lock);
        private = t->private;
-       if (private->number != paddc->num_counters) {
+       if (private->number != tmp.num_counters) {
                ret = -EINVAL;
                goto unlock_up_free;
        }