aboutsummaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
authorAndrey Ignatov <rdna@fb.com>2018-05-10 10:59:34 -0700
committerMoyster <oysterized@gmail.com>2019-05-03 19:07:46 +0200
commita8cc816f7f0f2ddf539e93015ce9f0aaaccd368f (patch)
treeca2f0fccc5acf5ffc5649f2bdc06c94d0d9d7198 /net/ipv4
parent2ff4ee8af83e18d87fb64ee0979d9aaa78eac153 (diff)
ipv4: fix memory leaks in udp_sendmsg, ping_v4_sendmsg
commit 1b97013bfb11d66f041de691de6f0fec748ce016 upstream. 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) Change-Id: I01537e9cbad24816d6fc1baeb6bd6d96bd10990a Signed-off-by: Andrey Ignatov <rdna@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/ipv4')
-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 216dc5efc..16e73ec15 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -769,8 +769,10 @@ int ping_v4_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;
}
tos = RT_TOS(inet->tos);
@@ -836,6 +838,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 027fe608b..afc4f5fe0 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -976,8 +976,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;
}
@@ -1083,6 +1085,7 @@ do_append_data:
out:
ip_rt_put(rt);
+out_free:
if (free)
kfree(ipc.opt);
if (!err)