Commit 08c0cad69f32ad1e881fa3fb7f5e0a25db5b07ce

Authored by Valentina Giusti
Committed by Pablo Neira Ayuso
1 parent 534473c608

netfilter: nfnetlink_queue: enable UID/GID socket info retrieval

Thanks to commits 41063e9 (ipv4: Early TCP socket demux) and 421b388
(udp: ipv4: Add udp early demux) it is now possible to parse UID and
GID socket info also for incoming TCP and UDP connections. Having
this info available, it is convenient to let NFQUEUE parse it in
order to improve and refine the traffic analysis in userspace.

Signed-off-by: Valentina Giusti <valentina.giusti@bmw-carit.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Showing 2 changed files with 38 additions and 1 deletions Side-by-side Diff

include/uapi/linux/netfilter/nfnetlink_queue.h
... ... @@ -47,6 +47,8 @@
47 47 NFQA_CAP_LEN, /* __u32 length of captured packet */
48 48 NFQA_SKB_INFO, /* __u32 skb meta information */
49 49 NFQA_EXP, /* nf_conntrack_netlink.h */
  50 + NFQA_UID, /* __u32 sk uid */
  51 + NFQA_GID, /* __u32 sk gid */
50 52  
51 53 __NFQA_MAX
52 54 };
... ... @@ -99,7 +101,8 @@
99 101 #define NFQA_CFG_F_FAIL_OPEN (1 << 0)
100 102 #define NFQA_CFG_F_CONNTRACK (1 << 1)
101 103 #define NFQA_CFG_F_GSO (1 << 2)
102   -#define NFQA_CFG_F_MAX (1 << 3)
  104 +#define NFQA_CFG_F_UID_GID (1 << 3)
  105 +#define NFQA_CFG_F_MAX (1 << 4)
103 106  
104 107 /* flags for NFQA_SKB_INFO */
105 108 /* packet appears to have wrong checksums, but they are ok */
net/netfilter/nfnetlink_queue_core.c
... ... @@ -297,6 +297,31 @@
297 297 return flags ? nla_put_be32(nlskb, NFQA_SKB_INFO, htonl(flags)) : 0;
298 298 }
299 299  
  300 +static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk)
  301 +{
  302 + const struct cred *cred;
  303 +
  304 + if (sk->sk_state == TCP_TIME_WAIT)
  305 + return 0;
  306 +
  307 + read_lock_bh(&sk->sk_callback_lock);
  308 + if (sk->sk_socket && sk->sk_socket->file) {
  309 + cred = sk->sk_socket->file->f_cred;
  310 + if (nla_put_be32(skb, NFQA_UID,
  311 + htonl(from_kuid_munged(&init_user_ns, cred->fsuid))))
  312 + goto nla_put_failure;
  313 + if (nla_put_be32(skb, NFQA_GID,
  314 + htonl(from_kgid_munged(&init_user_ns, cred->fsgid))))
  315 + goto nla_put_failure;
  316 + }
  317 + read_unlock_bh(&sk->sk_callback_lock);
  318 + return 0;
  319 +
  320 +nla_put_failure:
  321 + read_unlock_bh(&sk->sk_callback_lock);
  322 + return -1;
  323 +}
  324 +
300 325 static struct sk_buff *
301 326 nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
302 327 struct nf_queue_entry *entry,
... ... @@ -372,6 +397,11 @@
372 397 if (queue->flags & NFQA_CFG_F_CONNTRACK)
373 398 ct = nfqnl_ct_get(entskb, &size, &ctinfo);
374 399  
  400 + if (queue->flags & NFQA_CFG_F_UID_GID) {
  401 + size += (nla_total_size(sizeof(u_int32_t)) /* uid */
  402 + + nla_total_size(sizeof(u_int32_t))); /* gid */
  403 + }
  404 +
375 405 skb = nfnetlink_alloc_skb(net, size, queue->peer_portid,
376 406 GFP_ATOMIC);
377 407 if (!skb)
... ... @@ -483,6 +513,10 @@
483 513 if (nla_put(skb, NFQA_TIMESTAMP, sizeof(ts), &ts))
484 514 goto nla_put_failure;
485 515 }
  516 +
  517 + if ((queue->flags & NFQA_CFG_F_UID_GID) && entskb->sk &&
  518 + nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
  519 + goto nla_put_failure;
486 520  
487 521 if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0)
488 522 goto nla_put_failure;