From 03d35398dbbac00a92164b8ae4af34407576309e Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Tue, 13 Apr 2021 15:59:41 -0700 Subject: [PATCH] ANDROID: xt_qtaguid: fix UAF race Make sure to hold the sock_tag_list_lock while accessing the tag to avoid a race between getting the tag and free'ing the tag. Mot-CRs-fixed: (CR) CVE-Fixed: CVE-2021-0695 Bug: 184018316 Fixes: c7ca0ac69702 ("ANDROID: netfilter: xt_qtaguid: add qtaguid matching module") Signed-off-by: Will McVicker Change-Id: I62404bdaa602586e00821a7d4c5f9b9868a0e90a Signed-off-by: Gajjala Chakradhar Reviewed-on: https://gerrit.mot.com/2045010 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Xiangpo Zhao Submit-Approved: Jira Key (cherry picked from commit e04c6a8a906faadbcd7af351538461ded66c6bae) --- net/netfilter/xt_qtaguid.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index a61f43674519..635fcf7a8a8e 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -1067,18 +1067,6 @@ static struct sock_tag *get_sock_stat_nl(const struct sock *sk) return sock_tag_tree_search(&sock_tag_tree, sk); } -static struct sock_tag *get_sock_stat(const struct sock *sk) -{ - struct sock_tag *sock_tag_entry; - MT_DEBUG("qtaguid: get_sock_stat(sk=%p)\n", sk); - if (!sk) - return NULL; - spin_lock_bh(&sock_tag_list_lock); - sock_tag_entry = get_sock_stat_nl(sk); - spin_unlock_bh(&sock_tag_list_lock); - return sock_tag_entry; -} - static int ipx_proto(const struct sk_buff *skb, struct xt_action_param *par) { @@ -1313,12 +1301,15 @@ static void if_tag_stat_update(const char *ifname, uid_t uid, * Look for a tagged sock. * It will have an acct_uid. */ - sock_tag_entry = get_sock_stat(sk); + spin_lock_bh(&sock_tag_list_lock); + sock_tag_entry = sk ? get_sock_stat_nl(sk) : NULL; if (sock_tag_entry) { tag = sock_tag_entry->tag; acct_tag = get_atag_from_tag(tag); uid_tag = get_utag_from_tag(tag); - } else { + } + spin_unlock_bh(&sock_tag_list_lock); + if (!sock_tag_entry) { acct_tag = make_atag_from_value(0); tag = combine_atag_with_uid(acct_tag, uid); uid_tag = make_tag_from_uid(uid); -- 2.20.1