| From: Andrey Ignatov <rdna@fb.com> |
| Date: Thu, 10 May 2018 10:59:34 -0700 |
| Subject: 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) |
| 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> |
| --- |
| net/ipv4/ping.c | 7 +++++-- |
| net/ipv4/udp.c | 7 +++++-- |
| 2 files changed, 10 insertions(+), 4 deletions(-) |
| |
| --- a/net/ipv4/ping.c |
| +++ b/net/ipv4/ping.c |
| @@ -779,8 +779,10 @@ static int ping_v4_sendmsg(struct kiocb |
| 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); |
| @@ -845,6 +847,7 @@ back_from_confirm: |
| |
| out: |
| ip_rt_put(rt); |
| +out_free: |
| if (free) |
| kfree(ipc.opt); |
| if (!err) { |
| --- a/net/ipv4/udp.c |
| +++ b/net/ipv4/udp.c |
| @@ -997,8 +997,10 @@ int udp_sendmsg(struct kiocb *iocb, stru |
| 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; |
| } |
| @@ -1103,6 +1105,7 @@ do_append_data: |
| |
| out: |
| ip_rt_put(rt); |
| +out_free: |
| if (free) |
| kfree(ipc.opt); |
| if (!err) |