aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2013-04-25 02:53:54 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-29 13:21:30 -0400
commite8d9612c181b1a68ba5f71384629343466f1bd13 (patch)
tree16093300e9da78c1c3e272283ae4886d7b3984e8 /net
parent76d0eeb1a1579453cfd7c4da22004d4b34187ab4 (diff)
sock_diag: allow to dump bpf filters
This patch allows to dump BPF filters attached to a socket with SO_ATTACH_FILTER. Note that we check CAP_SYS_ADMIN before allowing to dump this info. For now, only AF_PACKET sockets use this feature. Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/sock_diag.c33
-rw-r--r--net/packet/diag.c4
2 files changed, 37 insertions, 0 deletions
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index a29e90cf36b7..d5bef0b0f639 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -49,6 +49,39 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
49} 49}
50EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); 50EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
51 51
52int 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
79out:
80 rcu_read_unlock();
81 return err;
82}
83EXPORT_SYMBOL(sock_diag_put_filterinfo);
84
52void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) 85void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
53{ 86{
54 mutex_lock(&sock_diag_table_mutex); 87 mutex_lock(&sock_diag_table_mutex);
diff --git a/net/packet/diag.c b/net/packet/diag.c
index 822fe9b33a49..a9584a2f6d69 100644
--- a/net/packet/diag.c
+++ b/net/packet/diag.c
@@ -170,6 +170,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
170 sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO)) 170 sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO))
171 goto out_nlmsg_trim; 171 goto out_nlmsg_trim;
172 172
173 if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
174 sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER))
175 goto out_nlmsg_trim;
176
173 return nlmsg_end(skb, nlh); 177 return nlmsg_end(skb, nlh);
174 178
175out_nlmsg_trim: 179out_nlmsg_trim: