summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Ignatov <rdna@fb.com>2018-05-10 10:59:34 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-05-25 10:54:51 +0200
commitfb1048128f9db7604a2163e237f8110ddef98cac (patch)
treefb59f645735b45d464a44adccaef0bdeb7e03f87
parent7eaa949984a07437bbc3d5c438ff66d72dd9e118 (diff)
downloadlinux-rt-fb1048128f9db7604a2163e237f8110ddef98cac.tar.gz
ipv4: fix memory leaks in udp_sendmsg, ping_v4_sendmsg
[ 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>
-rw-r--r--net/ipv4/ping.c7
-rw-r--r--net/ipv4/udp.c7
2 files changed, 10 insertions, 4 deletions
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 148678dd045c..7d41b0bfc872 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -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) {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 0f6d4d404e92..73b5235b032f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -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)