Commit 893acf3c authored by Chris Wright's avatar Chris Wright

[PATCH] Netfilter: do_add_counters race, possible oops or info leak (CVE-2006-0039)

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: default avatarChris Wright <chrisw@sous-sol.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9a4a3539
...@@ -941,7 +941,7 @@ static int do_add_counters(void __user *user, unsigned int len) ...@@ -941,7 +941,7 @@ static int do_add_counters(void __user *user, unsigned int len)
write_lock_bh(&t->lock); write_lock_bh(&t->lock);
private = t->private; private = t->private;
if (private->number != paddc->num_counters) { if (private->number != tmp.num_counters) {
ret = -EINVAL; ret = -EINVAL;
goto unlock_up_free; goto unlock_up_free;
} }
......
...@@ -1063,7 +1063,7 @@ do_add_counters(void __user *user, unsigned int len) ...@@ -1063,7 +1063,7 @@ do_add_counters(void __user *user, unsigned int len)
write_lock_bh(&t->lock); write_lock_bh(&t->lock);
private = t->private; private = t->private;
if (private->number != paddc->num_counters) { if (private->number != tmp.num_counters) {
ret = -EINVAL; ret = -EINVAL;
goto unlock_up_free; goto unlock_up_free;
} }
......
...@@ -1120,7 +1120,7 @@ do_add_counters(void __user *user, unsigned int len) ...@@ -1120,7 +1120,7 @@ do_add_counters(void __user *user, unsigned int len)
write_lock_bh(&t->lock); write_lock_bh(&t->lock);
private = t->private; private = t->private;
if (private->number != paddc->num_counters) { if (private->number != tmp.num_counters) {
ret = -EINVAL; ret = -EINVAL;
goto unlock_up_free; goto unlock_up_free;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment