summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2014-04-23 17:26:25 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-24 13:44:53 -0400
commita53b72c83a4216f2eb883ed45a0cbce014b8e62d (patch)
treee5a7f73a70a53c3485f3147de60f7c77b1ab7f4f /net
parent5187cd055b6e81fc6526109456f8b20623148d5f (diff)
net: Move the permission check in sock_diag_put_filterinfo to packet_diag_dump
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>
Diffstat (limited to 'net')
-rw-r--r--net/core/sock_diag.c4
-rw-r--r--net/packet/diag.c7
2 files changed, 8 insertions, 3 deletions
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index 9deb6abd6cf6..a4216a4c9572 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -49,7 +49,7 @@ 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 sock *sk, 52int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
53 struct sk_buff *skb, int attrtype) 53 struct sk_buff *skb, int attrtype)
54{ 54{
55 struct sock_fprog_kern *fprog; 55 struct sock_fprog_kern *fprog;
@@ -58,7 +58,7 @@ int sock_diag_put_filterinfo(struct sock *sk,
58 unsigned int flen; 58 unsigned int flen;
59 int err = 0; 59 int err = 0;
60 60
61 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { 61 if (!may_report_filterinfo) {
62 nla_reserve(skb, attrtype, 0); 62 nla_reserve(skb, attrtype, 0);
63 return 0; 63 return 0;
64 } 64 }
diff --git a/net/packet/diag.c b/net/packet/diag.c
index 435ff99ba8c7..b34d0de24091 100644
--- a/net/packet/diag.c
+++ b/net/packet/diag.c
@@ -128,6 +128,7 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb)
128 128
129static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, 129static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
130 struct packet_diag_req *req, 130 struct packet_diag_req *req,
131 bool may_report_filterinfo,
131 struct user_namespace *user_ns, 132 struct user_namespace *user_ns,
132 u32 portid, u32 seq, u32 flags, int sk_ino) 133 u32 portid, u32 seq, u32 flags, int sk_ino)
133{ 134{
@@ -172,7 +173,8 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
172 goto out_nlmsg_trim; 173 goto out_nlmsg_trim;
173 174
174 if ((req->pdiag_show & PACKET_SHOW_FILTER) && 175 if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
175 sock_diag_put_filterinfo(sk, skb, PACKET_DIAG_FILTER)) 176 sock_diag_put_filterinfo(may_report_filterinfo, sk, skb,
177 PACKET_DIAG_FILTER))
176 goto out_nlmsg_trim; 178 goto out_nlmsg_trim;
177 179
178 return nlmsg_end(skb, nlh); 180 return nlmsg_end(skb, nlh);
@@ -188,9 +190,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
188 struct packet_diag_req *req; 190 struct packet_diag_req *req;
189 struct net *net; 191 struct net *net;
190 struct sock *sk; 192 struct sock *sk;
193 bool may_report_filterinfo;
191 194
192 net = sock_net(skb->sk); 195 net = sock_net(skb->sk);
193 req = nlmsg_data(cb->nlh); 196 req = nlmsg_data(cb->nlh);
197 may_report_filterinfo = ns_capable(net->user_ns, CAP_NET_ADMIN);
194 198
195 mutex_lock(&net->packet.sklist_lock); 199 mutex_lock(&net->packet.sklist_lock);
196 sk_for_each(sk, &net->packet.sklist) { 200 sk_for_each(sk, &net->packet.sklist) {
@@ -200,6 +204,7 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
200 goto next; 204 goto next;
201 205
202 if (sk_diag_fill(sk, skb, req, 206 if (sk_diag_fill(sk, skb, req,
207 may_report_filterinfo,
203 sk_user_ns(NETLINK_CB(cb->skb).sk), 208 sk_user_ns(NETLINK_CB(cb->skb).sk),
204 NETLINK_CB(cb->skb).portid, 209 NETLINK_CB(cb->skb).portid,
205 cb->nlh->nlmsg_seq, NLM_F_MULTI, 210 cb->nlh->nlmsg_seq, NLM_F_MULTI,