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:
Todd Kjos committed 2026-08-11 13:34:02 -07:00
1 parent b209fee2f5
commit 4fa3c1db38
1 file changed
+8 -7
+8 -7
View File
@@ -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)