diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2013-04-25 02:53:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-29 13:21:30 -0400 |
commit | e8d9612c181b1a68ba5f71384629343466f1bd13 (patch) | |
tree | 16093300e9da78c1c3e272283ae4886d7b3984e8 /net | |
parent | 76d0eeb1a1579453cfd7c4da22004d4b34187ab4 (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.c | 33 | ||||
-rw-r--r-- | net/packet/diag.c | 4 |
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 | } |
50 | EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); | 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 | void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) | 85 | void 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 | ||
175 | out_nlmsg_trim: | 179 | out_nlmsg_trim: |