]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ipv4: fix memory leaks in udp_sendmsg, ping_v4_sendmsg
authorAndrey Ignatov <rdna@fb.com>
Thu, 10 May 2018 17:59:34 +0000 (10:59 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 May 2018 08:54:51 +0000 (10:54 +0200)
[ Upstream commit 1b97013bfb11d66f041de691de6f0fec748ce016 ]

Fix more memory leaks in ip_cmsg_send() callers. Part of them were fixed
earlier in 919483096bfe.

* udp_sendmsg one was there since the beginning when linux sources were
  first added to git;
* ping_v4_sendmsg one was copy/pasted in c319b4d76b9e.

Whenever return happens in udp_sendmsg() or ping_v4_sendmsg() IP options
have to be freed if they were allocated previously.

Add label so that future callers (if any) can use it instead of kfree()
before return that is easy to forget.

Fixes: c319b4d76b9e (net: ipv4: add IPPROTO_ICMP socket kind)
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/ipv4/ping.c
net/ipv4/udp.c

index 148678dd045cb3cb4dca7fd56822b8358d7e839f..7d41b0bfc872c95e76b555c1a14f9695bf12cb1d 100644 (file)
@@ -771,8 +771,10 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
        ipc.addr = faddr = daddr;
 
        if (ipc.opt && ipc.opt->opt.srr) {
-               if (!daddr)
-                       return -EINVAL;
+               if (!daddr) {
+                       err = -EINVAL;
+                       goto out_free;
+               }
                faddr = ipc.opt->opt.faddr;
        }
        tos = get_rttos(&ipc, inet);
@@ -837,6 +839,7 @@ back_from_confirm:
 
 out:
        ip_rt_put(rt);
+out_free:
        if (free)
                kfree(ipc.opt);
        if (!err) {
index 0f6d4d404e920d23e41cb35078e906d345f3025b..73b5235b032f2374a3564d93f6246d91b2131129 100644 (file)
@@ -975,8 +975,10 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        ipc.addr = faddr = daddr;
 
        if (ipc.opt && ipc.opt->opt.srr) {
-               if (!daddr)
-                       return -EINVAL;
+               if (!daddr) {
+                       err = -EINVAL;
+                       goto out_free;
+               }
                faddr = ipc.opt->opt.faddr;
                connected = 0;
        }
@@ -1081,6 +1083,7 @@ do_append_data:
 
 out:
        ip_rt_put(rt);
+out_free:
        if (free)
                kfree(ipc.opt);
        if (!err)