ANDROID: netfilter: xt_quota2: fix UAF in q2_get_counter error path
In q2_get_counter(), a new counter entry is added to counter_list
and counter_list_lock is released before proc_create_data() is
invoked. During this window, another thread can locate the counter
in counter_list and increment its reference count via
atomic_inc(&e->ref).
If proc_create_data() subsequently fails, the error handling path
previously called list_del() and kfree() unconditionally, ignoring
the refcount. If another thread acquired a reference in the interim,
this resulted in a Use-After-Free (UAF) condition.
Fix this by using atomic_dec_and_test(&e->ref) under
counter_list_lock when proc_create_data() fails. Only remove from
counter_list and free the memory if the refcount reaches zero. If
another thread holds a reference, set procfs_entry to NULL and
leave the counter intact for the surviving thread.
Fixes: 2e134f75ce91 ("ANDROID: netfilter: xt_quota2: add quota2 from xtables-addons")
Bug: 499166786
Change-Id: I1270d6d94ec0bd6a83858ad053434dae0393b7e3
Signed-off-by: Todd Kjos <tkjos@google.com>
This commit is contained in:
1 parent
b209fee2f5
commit
4fa3c1db38
1 file changed
+8
-7
@@ -209,7 +209,7 @@ q2_get_counter(const struct xt_quota_mtinfo2 *q)
|
||||
/* No need to hold a lock while getting a new counter */
|
||||
new_e = q2_new_counter(q, false);
|
||||
if (new_e == NULL)
|
||||
goto out;
|
||||
return NULL;
|
||||
|
||||
spin_lock_bh(&counter_list_lock);
|
||||
list_for_each_entry(e, &counter_list, list)
|
||||
@@ -238,16 +238,17 @@ q2_get_counter(const struct xt_quota_mtinfo2 *q)
|
||||
|
||||
if (IS_ERR_OR_NULL(p)) {
|
||||
spin_lock_bh(&counter_list_lock);
|
||||
list_del(&e->list);
|
||||
if (atomic_dec_and_test(&e->ref)) {
|
||||
list_del(&e->list);
|
||||
kfree(e);
|
||||
} else {
|
||||
e->procfs_entry = NULL;
|
||||
}
|
||||
spin_unlock_bh(&counter_list_lock);
|
||||
goto out;
|
||||
return NULL;
|
||||
}
|
||||
proc_set_user(p, quota_list_uid, quota_list_gid);
|
||||
return e;
|
||||
|
||||
out:
|
||||
kfree(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int quota_mt2_check(const struct xt_mtchk_param *par)
|
||||
|
||||
Reference in new issue
Block a user