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