@@ -16,6 +16,7 @@
#include <linux/netfilter/nf_tables.h>
#include <net/dst.h>
#include <net/sock.h>
+#include <net/tcp_states.h> /* for TCP_TIME_WAIT */
#include <net/netfilter/nf_tables.h>
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_kgid_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: {
net/netfilter/nft_meta.c: In function ‘nft_meta_eval’: net/netfilter/nft_meta.c:82:17: error: incompatible types when assigning to type ‘u32’ from type ‘kuid_t’ net/netfilter/nft_meta.c:88:17: error: incompatible types when assigning to type ‘u32’ from type ‘kgid_t’ Reported-by: Bjørnar Ness <bjornar.ness@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/nft_meta.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-)