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;
> +}
> +

Reply via email to