Commit 7ae836a3 authored by Phil Sutter's avatar Phil Sutter Committed by Pablo Neira Ayuso

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: 0265ab44 ("[NETFILTER]: merge ipt_owner/ip6t_owner in xt_owner")
Reported-by: default avatarJann Horn <jannh@google.com>
Signed-off-by: default avatarPhil Sutter <phil@nwl.cc>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent f6e1532a
...@@ -76,19 +76,24 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) ...@@ -76,19 +76,24 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
*/ */
return false; return false;
filp = sk->sk_socket->file; read_lock_bh(&sk->sk_callback_lock);
if (filp == NULL) filp = sk->sk_socket ? sk->sk_socket->file : NULL;
if (filp == NULL) {
read_unlock_bh(&sk->sk_callback_lock);
return ((info->match ^ info->invert) & return ((info->match ^ info->invert) &
(XT_OWNER_UID | XT_OWNER_GID)) == 0; (XT_OWNER_UID | XT_OWNER_GID)) == 0;
}
if (info->match & XT_OWNER_UID) { if (info->match & XT_OWNER_UID) {
kuid_t uid_min = make_kuid(net->user_ns, info->uid_min); kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
kuid_t uid_max = make_kuid(net->user_ns, info->uid_max); kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
if ((uid_gte(filp->f_cred->fsuid, uid_min) && if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
uid_lte(filp->f_cred->fsuid, uid_max)) ^ uid_lte(filp->f_cred->fsuid, uid_max)) ^
!(info->invert & XT_OWNER_UID)) !(info->invert & XT_OWNER_UID)) {
read_unlock_bh(&sk->sk_callback_lock);
return false; return false;
} }
}
if (info->match & XT_OWNER_GID) { if (info->match & XT_OWNER_GID) {
unsigned int i, match = false; unsigned int i, match = false;
...@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) ...@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
} }
} }
if (match ^ !(info->invert & XT_OWNER_GID)) if (match ^ !(info->invert & XT_OWNER_GID)) {
read_unlock_bh(&sk->sk_callback_lock);
return false; return false;
} }
}
read_unlock_bh(&sk->sk_callback_lock);
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment