aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h5
-rw-r--r--net/netfilter/nfnetlink_queue_core.c34
2 files changed, 38 insertions, 1 deletions
diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index 0132bad79de7..8dd819e2b5fe 100644
--- a/include/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
@@ -47,6 +47,8 @@ enum nfqnl_attr_type {
47 NFQA_CAP_LEN, /* __u32 length of captured packet */ 47 NFQA_CAP_LEN, /* __u32 length of captured packet */
48 NFQA_SKB_INFO, /* __u32 skb meta information */ 48 NFQA_SKB_INFO, /* __u32 skb meta information */
49 NFQA_EXP, /* nf_conntrack_netlink.h */ 49 NFQA_EXP, /* nf_conntrack_netlink.h */
50 NFQA_UID, /* __u32 sk uid */
51 NFQA_GID, /* __u32 sk gid */
50 52
51 __NFQA_MAX 53 __NFQA_MAX
52}; 54};
@@ -99,7 +101,8 @@ enum nfqnl_attr_config {
99#define NFQA_CFG_F_FAIL_OPEN (1 << 0) 101#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
100#define NFQA_CFG_F_CONNTRACK (1 << 1) 102#define NFQA_CFG_F_CONNTRACK (1 << 1)
101#define NFQA_CFG_F_GSO (1 << 2) 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/* flags for NFQA_SKB_INFO */ 107/* flags for NFQA_SKB_INFO */
105/* packet appears to have wrong checksums, but they are ok */ 108/* packet appears to have wrong checksums, but they are ok */
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 21258cf70091..d3cf12b83174 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -297,6 +297,31 @@ nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
297 return flags ? nla_put_be32(nlskb, NFQA_SKB_INFO, htonl(flags)) : 0; 297 return flags ? nla_put_be32(nlskb, NFQA_SKB_INFO, htonl(flags)) : 0;
298} 298}
299 299
300static 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
320nla_put_failure:
321 read_unlock_bh(&sk->sk_callback_lock);
322 return -1;
323}
324
300static struct sk_buff * 325static struct sk_buff *
301nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, 326nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
302 struct nf_queue_entry *entry, 327 struct nf_queue_entry *entry,
@@ -372,6 +397,11 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
372 if (queue->flags & NFQA_CFG_F_CONNTRACK) 397 if (queue->flags & NFQA_CFG_F_CONNTRACK)
373 ct = nfqnl_ct_get(entskb, &size, &ctinfo); 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 skb = nfnetlink_alloc_skb(net, size, queue->peer_portid, 405 skb = nfnetlink_alloc_skb(net, size, queue->peer_portid,
376 GFP_ATOMIC); 406 GFP_ATOMIC);
377 if (!skb) 407 if (!skb)
@@ -484,6 +514,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
484 goto nla_put_failure; 514 goto nla_put_failure;
485 } 515 }
486 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;
520
487 if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0) 521 if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0)
488 goto nla_put_failure; 522 goto nla_put_failure;
489 523