]> err.no Git - linux-2.6/commitdiff
[NETFILTER]: Fix do_add_counters race, possible oops or info leak (CVE-2006-0039)
authorSolar Designer <solar@openwall.com>
Fri, 19 May 2006 09:16:52 +0000 (02:16 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 19 May 2006 09:16:52 +0000 (02:16 -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.

Signed-off-by: Solar Designer <solar@openwall.com>
Signed-off-by: Kirill Korotaev <dev@openvz.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/netfilter/arp_tables.c
net/ipv6/netfilter/ip6_tables.c

index c2d92f99a2b8b0b18bc1f17e1ec742a2c6051de5..d0d19192026d9eb2327cf68a47a4ba1b23dc7fe5 100644 (file)
@@ -948,7 +948,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 0a673038344fe30142e0d095f3f6bb5c6a8854a8..2e72f89a7019929f2da18cb74ef1ba26e9d1d74b 100644 (file)
@@ -1103,7 +1103,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;
        }