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:
Родитель
5187cd055b
Коммит
a53b72c83a
|
@ -23,7 +23,7 @@ int sock_diag_check_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_filterinfo(struct sock *sk,
|
||||
int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
|
||||
struct sk_buff *skb, int attrtype);
|
||||
|
||||
#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);
|
||||
|
||||
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 sock_fprog_kern *fprog;
|
||||
|
@ -58,7 +58,7 @@ int sock_diag_put_filterinfo(struct sock *sk,
|
|||
unsigned int flen;
|
||||
int err = 0;
|
||||
|
||||
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
|
||||
if (!may_report_filterinfo) {
|
||||
nla_reserve(skb, attrtype, 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,
|
||||
struct packet_diag_req *req,
|
||||
bool may_report_filterinfo,
|
||||
struct user_namespace *user_ns,
|
||||
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;
|
||||
|
||||
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);
|
||||
|
@ -188,9 +190,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) {
|
||||
|
@ -200,6 +204,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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче