Re: [PATCH] net: ip, diag -- Add diag interface for raw sockets

From: Eric Dumazet
Date: Fri Sep 09 2016 - 15:55:35 EST


On Fri, 2016-09-09 at 21:26 +0300, Cyrill Gorcunov wrote:

...

> +static int raw_diag_dump_one(struct sk_buff *in_skb,
> + const struct nlmsghdr *nlh,
> + const struct inet_diag_req_v2 *r)
> +{
> + struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
> + struct net *net = sock_net(in_skb->sk);
> + struct sock *sk = NULL, *s;
> + int err = -ENOENT, slot;
> + struct sk_buff *rep;
> +
> + if (IS_ERR(hashinfo))
> + return PTR_ERR(hashinfo);
> +
> + read_lock(&hashinfo->lock);
> + for (slot = 0; slot < RAW_HTABLE_SIZE; slot++) {
> + sk_for_each(s, &hashinfo->ht[slot]) {
> + sk = raw_lookup(net, s, r);
> + if (sk)
> + break;
> + }
> + }
> + if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
> + sk = NULL;
> + read_unlock(&hashinfo->lock);
> + if (!sk)
> + return -ENOENT;
> +
> + rep = nlmsg_new(sizeof(struct inet_diag_msg) +
> + sizeof(struct inet_diag_meminfo) + 64,
> + GFP_KERNEL);
> + if (!rep)

There is a missing sock_put(sk)

> + return -ENOMEM;
> +
> + err = inet_sk_diag_fill(sk, NULL, rep, r,
> + sk_user_ns(NETLINK_CB(in_skb).sk),
> + NETLINK_CB(in_skb).portid,
> + nlh->nlmsg_seq, 0, nlh);

sock_put(sk);

> + if (err < 0) {
> + kfree_skb(rep);


> + return err;
> + }
> +
> + err = netlink_unicast(net->diag_nlsk, rep,
> + NETLINK_CB(in_skb).portid,
> + MSG_DONTWAIT);
> + if (err > 0)
> + err = 0;
> + return err;
> +}
> +