Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'pktdiag'

Nicolas Dichtel says:

====================
The goal of this patchset is to be able to get all infos exported via the
/proc/net/packet and also beeing able to get filter associated to af_packet
sockets.

As usual, the patch against iproute2 will be sent once the patches are included
and net-next merged. I can send it on demand.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+63 -5
+3
include/linux/sock_diag.h
··· 1 1 #ifndef __SOCK_DIAG_H__ 2 2 #define __SOCK_DIAG_H__ 3 3 4 + #include <linux/user_namespace.h> 4 5 #include <uapi/linux/sock_diag.h> 5 6 6 7 struct sk_buff; ··· 23 22 void sock_diag_save_cookie(void *sk, __u32 *cookie); 24 23 25 24 int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); 25 + int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, 26 + struct sk_buff *skb, int attrtype); 26 27 27 28 #endif
+5
include/uapi/linux/packet_diag.h
··· 16 16 #define PACKET_SHOW_MCLIST 0x00000002 /* A set of packet_diag_mclist-s */ 17 17 #define PACKET_SHOW_RING_CFG 0x00000004 /* Rings configuration parameters */ 18 18 #define PACKET_SHOW_FANOUT 0x00000008 19 + #define PACKET_SHOW_MEMINFO 0x00000010 20 + #define PACKET_SHOW_FILTER 0x00000020 19 21 20 22 struct packet_diag_msg { 21 23 __u8 pdiag_family; ··· 34 32 PACKET_DIAG_RX_RING, 35 33 PACKET_DIAG_TX_RING, 36 34 PACKET_DIAG_FANOUT, 35 + PACKET_DIAG_UID, 36 + PACKET_DIAG_MEMINFO, 37 + PACKET_DIAG_FILTER, 37 38 38 39 __PACKET_DIAG_MAX, 39 40 };
+33
net/core/sock_diag.c
··· 49 49 } 50 50 EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); 51 51 52 + int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, 53 + struct sk_buff *skb, int attrtype) 54 + { 55 + struct nlattr *attr; 56 + struct sk_filter *filter; 57 + unsigned int len; 58 + int err = 0; 59 + 60 + if (!ns_capable(user_ns, CAP_NET_ADMIN)) { 61 + nla_reserve(skb, attrtype, 0); 62 + return 0; 63 + } 64 + 65 + rcu_read_lock(); 66 + 67 + filter = rcu_dereference(sk->sk_filter); 68 + len = filter ? filter->len * sizeof(struct sock_filter) : 0; 69 + 70 + attr = nla_reserve(skb, attrtype, len); 71 + if (attr == NULL) { 72 + err = -EMSGSIZE; 73 + goto out; 74 + } 75 + 76 + if (filter) 77 + memcpy(nla_data(attr), filter->insns, len); 78 + 79 + out: 80 + rcu_read_unlock(); 81 + return err; 82 + } 83 + EXPORT_SYMBOL(sock_diag_put_filterinfo); 84 + 52 85 void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) 53 86 { 54 87 mutex_lock(&sock_diag_table_mutex);
+22 -5
net/packet/diag.c
··· 125 125 return ret; 126 126 } 127 127 128 - static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req, 129 - u32 portid, u32 seq, u32 flags, int sk_ino) 128 + static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, 129 + struct packet_diag_req *req, 130 + struct user_namespace *user_ns, 131 + u32 portid, u32 seq, u32 flags, int sk_ino) 130 132 { 131 133 struct nlmsghdr *nlh; 132 134 struct packet_diag_msg *rp; ··· 149 147 pdiag_put_info(po, skb)) 150 148 goto out_nlmsg_trim; 151 149 150 + if ((req->pdiag_show & PACKET_SHOW_INFO) && 151 + nla_put_u32(skb, PACKET_DIAG_UID, 152 + from_kuid_munged(user_ns, sock_i_uid(sk)))) 153 + goto out_nlmsg_trim; 154 + 152 155 if ((req->pdiag_show & PACKET_SHOW_MCLIST) && 153 156 pdiag_put_mclist(po, skb)) 154 157 goto out_nlmsg_trim; ··· 164 157 165 158 if ((req->pdiag_show & PACKET_SHOW_FANOUT) && 166 159 pdiag_put_fanout(po, skb)) 160 + goto out_nlmsg_trim; 161 + 162 + if ((req->pdiag_show & PACKET_SHOW_MEMINFO) && 163 + sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO)) 164 + goto out_nlmsg_trim; 165 + 166 + if ((req->pdiag_show & PACKET_SHOW_FILTER) && 167 + sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER)) 167 168 goto out_nlmsg_trim; 168 169 169 170 return nlmsg_end(skb, nlh); ··· 198 183 if (num < s_num) 199 184 goto next; 200 185 201 - if (sk_diag_fill(sk, skb, req, NETLINK_CB(cb->skb).portid, 202 - cb->nlh->nlmsg_seq, NLM_F_MULTI, 203 - sock_i_ino(sk)) < 0) 186 + if (sk_diag_fill(sk, skb, req, 187 + sk_user_ns(NETLINK_CB(cb->skb).sk), 188 + NETLINK_CB(cb->skb).portid, 189 + cb->nlh->nlmsg_seq, NLM_F_MULTI, 190 + sock_i_ino(sk)) < 0) 204 191 goto done; 205 192 next: 206 193 num++;