Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: xt_owner: Fix for unsafe access of sk->sk_socket

A concurrently running sock_orphan() may NULL the sk_socket pointer in
between check and deref. Follow other users (like nft_meta.c for
instance) and acquire sk_callback_lock before dereferencing sk_socket.

Fixes: 0265ab44bacc ("[NETFILTER]: merge ipt_owner/ip6t_owner in xt_owner")
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Phil Sutter and committed by
Pablo Neira Ayuso
7ae836a3 f6e1532a

+12 -4
+12 -4
net/netfilter/xt_owner.c
··· 76 76 */ 77 77 return false; 78 78 79 - filp = sk->sk_socket->file; 80 - if (filp == NULL) 79 + read_lock_bh(&sk->sk_callback_lock); 80 + filp = sk->sk_socket ? sk->sk_socket->file : NULL; 81 + if (filp == NULL) { 82 + read_unlock_bh(&sk->sk_callback_lock); 81 83 return ((info->match ^ info->invert) & 82 84 (XT_OWNER_UID | XT_OWNER_GID)) == 0; 85 + } 83 86 84 87 if (info->match & XT_OWNER_UID) { 85 88 kuid_t uid_min = make_kuid(net->user_ns, info->uid_min); 86 89 kuid_t uid_max = make_kuid(net->user_ns, info->uid_max); 87 90 if ((uid_gte(filp->f_cred->fsuid, uid_min) && 88 91 uid_lte(filp->f_cred->fsuid, uid_max)) ^ 89 - !(info->invert & XT_OWNER_UID)) 92 + !(info->invert & XT_OWNER_UID)) { 93 + read_unlock_bh(&sk->sk_callback_lock); 90 94 return false; 95 + } 91 96 } 92 97 93 98 if (info->match & XT_OWNER_GID) { ··· 117 112 } 118 113 } 119 114 120 - if (match ^ !(info->invert & XT_OWNER_GID)) 115 + if (match ^ !(info->invert & XT_OWNER_GID)) { 116 + read_unlock_bh(&sk->sk_callback_lock); 121 117 return false; 118 + } 122 119 } 123 120 121 + read_unlock_bh(&sk->sk_callback_lock); 124 122 return true; 125 123 } 126 124