]> Pileus Git - ~andy/linux/blobdiff - net/core/sock_diag.c
sock_diag: allow to dump bpf filters
[~andy/linux] / net / core / sock_diag.c
index a29e90cf36b75af6fd894494253cb6af554039c1..d5bef0b0f63968bdfc906921bcc99522154750cc 100644 (file)
@@ -49,6 +49,39 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
 }
 EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
 
+int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
+                            struct sk_buff *skb, int attrtype)
+{
+       struct nlattr *attr;
+       struct sk_filter *filter;
+       unsigned int len;
+       int err = 0;
+
+       if (!ns_capable(user_ns, CAP_NET_ADMIN)) {
+               nla_reserve(skb, attrtype, 0);
+               return 0;
+       }
+
+       rcu_read_lock();
+
+       filter = rcu_dereference(sk->sk_filter);
+       len = filter ? filter->len * sizeof(struct sock_filter) : 0;
+
+       attr = nla_reserve(skb, attrtype, len);
+       if (attr == NULL) {
+               err = -EMSGSIZE;
+               goto out;
+       }
+
+       if (filter)
+               memcpy(nla_data(attr), filter->insns, len);
+
+out:
+       rcu_read_unlock();
+       return err;
+}
+EXPORT_SYMBOL(sock_diag_put_filterinfo);
+
 void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
 {
        mutex_lock(&sock_diag_table_mutex);