ANDROID: xt_qtaguid: fix UAF race
authorWill McVicker <willmcvicker@google.com>
Tue, 13 Apr 2021 22:59:41 +0000 (15:59 -0700)
committerPDO SCM Team <hudsoncm@motorola.com>
Mon, 6 Sep 2021 11:26:05 +0000 (06:26 -0500)
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 <willmcvicker@google.com>
Change-Id: I62404bdaa602586e00821a7d4c5f9b9868a0e90a
Signed-off-by: Gajjala Chakradhar <gajjalac@motorola.com>
Reviewed-on: https://gerrit.mot.com/2045010
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key
(cherry picked from commit e04c6a8a906faadbcd7af351538461ded66c6bae)

net/netfilter/xt_qtaguid.c

index a61f4367451973ed7365bb7a1208436b4e80cfe7..635fcf7a8a8e45a00ed8086d69e981e2494e6f2f 100644 (file)
@@ -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);