Commit 08c0cad69f32ad1e881fa3fb7f5e0a25db5b07ce
Committed by
Pablo Neira Ayuso
1 parent
534473c608
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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; |