diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2014-04-23 14:26:25 -0700 |
---|---|---|
committer | Jiri Slaby <jslaby@suse.cz> | 2014-06-23 10:27:55 +0200 |
commit | 4dcecf4ce16a20c210e91a62ae28275418e3ed2c (patch) | |
tree | 6ec163cad2e160e5d2e11f5fbf6c7ff00ab53a9b /net/packet | |
parent | 4587dcd284963b76844da9932f6440aa312aec0a (diff) |
net: Move the permission check in sock_diag_put_filterinfo to packet_diag_dump
[ Upstream commit a53b72c83a4216f2eb883ed45a0cbce014b8e62d ]
The permission check in sock_diag_put_filterinfo is wrong, and it is so removed
from it's sources it is not clear why it is wrong. Move the computation
into packet_diag_dump and pass a bool of the result into sock_diag_filterinfo.
This does not yet correct the capability check but instead simply moves it to make
it clear what is going on.
Reported-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'net/packet')
-rw-r--r-- | net/packet/diag.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/net/packet/diag.c b/net/packet/diag.c index ec8b6e8a80b1..01cd1ac44ff5 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c @@ -127,6 +127,7 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb) static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req, + bool may_report_filterinfo, struct user_namespace *user_ns, u32 portid, u32 seq, u32 flags, int sk_ino) { @@ -171,7 +172,8 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, goto out_nlmsg_trim; if ((req->pdiag_show & PACKET_SHOW_FILTER) && - sock_diag_put_filterinfo(sk, skb, PACKET_DIAG_FILTER)) + sock_diag_put_filterinfo(may_report_filterinfo, sk, skb, + PACKET_DIAG_FILTER)) goto out_nlmsg_trim; return nlmsg_end(skb, nlh); @@ -187,9 +189,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) struct packet_diag_req *req; struct net *net; struct sock *sk; + bool may_report_filterinfo; net = sock_net(skb->sk); req = nlmsg_data(cb->nlh); + may_report_filterinfo = ns_capable(net->user_ns, CAP_NET_ADMIN); mutex_lock(&net->packet.sklist_lock); sk_for_each(sk, &net->packet.sklist) { @@ -199,6 +203,7 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) goto next; if (sk_diag_fill(sk, skb, req, + may_report_filterinfo, sk_user_ns(NETLINK_CB(cb->skb).sk), NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, |