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>
This commit is contained in:
parent
5187cd055b
commit
a53b72c83a
|
@ -23,7 +23,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie);
|
||||||
void sock_diag_save_cookie(void *sk, __u32 *cookie);
|
void sock_diag_save_cookie(void *sk, __u32 *cookie);
|
||||||
|
|
||||||
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
|
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
|
||||||
int sock_diag_put_filterinfo(struct sock *sk,
|
int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
|
||||||
struct sk_buff *skb, int attrtype);
|
struct sk_buff *skb, int attrtype);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,7 +49,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
|
EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
|
||||||
|
|
||||||
int sock_diag_put_filterinfo(struct sock *sk,
|
int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
|
||||||
struct sk_buff *skb, int attrtype)
|
struct sk_buff *skb, int attrtype)
|
||||||
{
|
{
|
||||||
struct sock_fprog_kern *fprog;
|
struct sock_fprog_kern *fprog;
|
||||||
|
@ -58,7 +58,7 @@ int sock_diag_put_filterinfo(struct sock *sk,
|
||||||
unsigned int flen;
|
unsigned int flen;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
|
if (!may_report_filterinfo) {
|
||||||
nla_reserve(skb, attrtype, 0);
|
nla_reserve(skb, attrtype, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,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,
|
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
|
||||||
struct packet_diag_req *req,
|
struct packet_diag_req *req,
|
||||||
|
bool may_report_filterinfo,
|
||||||
struct user_namespace *user_ns,
|
struct user_namespace *user_ns,
|
||||||
u32 portid, u32 seq, u32 flags, int sk_ino)
|
u32 portid, u32 seq, u32 flags, int sk_ino)
|
||||||
{
|
{
|
||||||
|
@ -172,7 +173,8 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
|
||||||
goto out_nlmsg_trim;
|
goto out_nlmsg_trim;
|
||||||
|
|
||||||
if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
|
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;
|
goto out_nlmsg_trim;
|
||||||
|
|
||||||
return nlmsg_end(skb, nlh);
|
return nlmsg_end(skb, nlh);
|
||||||
|
@ -188,9 +190,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
struct packet_diag_req *req;
|
struct packet_diag_req *req;
|
||||||
struct net *net;
|
struct net *net;
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
|
bool may_report_filterinfo;
|
||||||
|
|
||||||
net = sock_net(skb->sk);
|
net = sock_net(skb->sk);
|
||||||
req = nlmsg_data(cb->nlh);
|
req = nlmsg_data(cb->nlh);
|
||||||
|
may_report_filterinfo = ns_capable(net->user_ns, CAP_NET_ADMIN);
|
||||||
|
|
||||||
mutex_lock(&net->packet.sklist_lock);
|
mutex_lock(&net->packet.sklist_lock);
|
||||||
sk_for_each(sk, &net->packet.sklist) {
|
sk_for_each(sk, &net->packet.sklist) {
|
||||||
|
@ -200,6 +204,7 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (sk_diag_fill(sk, skb, req,
|
if (sk_diag_fill(sk, skb, req,
|
||||||
|
may_report_filterinfo,
|
||||||
sk_user_ns(NETLINK_CB(cb->skb).sk),
|
sk_user_ns(NETLINK_CB(cb->skb).sk),
|
||||||
NETLINK_CB(cb->skb).portid,
|
NETLINK_CB(cb->skb).portid,
|
||||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||||
|
|
Loading…
Reference in New Issue