diff options
| -rw-r--r-- | include/uapi/linux/netfilter/nfnetlink_queue.h | 5 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_queue_core.c | 34 |
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 | ||
| 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 | static struct sk_buff * | 325 | static struct sk_buff * |
| 301 | nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, | 326 | nfqnl_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 | ||
