diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 84256bc..4c6998d 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -16,6 +16,7 @@ #include #include #include +#include /* for TCP_TIME_WAIT */ #include struct nft_meta { @@ -76,16 +77,35 @@ static void nft_meta_eval(const struct nft_expr *expr, *(u16 *)dest->data = out->type; break; case NFT_META_SKUID: - if (skb->sk == NULL || skb->sk->sk_socket == NULL || - skb->sk->sk_socket->file == NULL) + if (skb->sk == NULL || skb->sk->sk_state == TCP_TIME_WAIT) goto err; - dest->data[0] = skb->sk->sk_socket->file->f_cred->fsuid; + + read_lock_bh(&skb->sk->sk_callback_lock); + if (skb->sk->sk_socket == NULL || + skb->sk->sk_socket->file == NULL) { + read_unlock_bh(&skb->sk->sk_callback_lock); + goto err; + } + + dest->data[0] = + from_kuid_munged(&init_user_ns, + skb->sk->sk_socket->file->f_cred->fsuid); + read_unlock_bh(&skb->sk->sk_callback_lock); break; case NFT_META_SKGID: - if (skb->sk == NULL || skb->sk->sk_socket == NULL || - skb->sk->sk_socket->file == NULL) + if (skb->sk == NULL || skb->sk->sk_state == TCP_TIME_WAIT) + goto err; + + read_lock_bh(&skb->sk->sk_callback_lock); + if (skb->sk->sk_socket == NULL || + skb->sk->sk_socket->file == NULL) { + read_unlock_bh(&skb->sk->sk_callback_lock); goto err; - dest->data[0] = skb->sk->sk_socket->file->f_cred->fsgid; + } + dest->data[0] = + from_kuid_munged(&init_user_ns, + skb->sk->sk_socket->file->f_cred->fsgid); + read_unlock_bh(&skb->sk->sk_callback_lock); break; #ifdef CONFIG_NET_CLS_ROUTE case NFT_META_RTCLASSID: {