aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndrey Ignatov <rdna@fb.com>2018-05-10 13:59:34 -0400
committerDavid S. Miller <davem@davemloft.net>2018-05-11 12:00:58 -0400
commit1b97013bfb11d66f041de691de6f0fec748ce016 (patch)
treef68daaa874de1b25206aaf0a81c04c455b5a8563 /net
parent8ccc113172e4c1ebef45c2433f3c32ed6ae1b9c9 (diff)
ipv4: fix memory leaks in udp_sendmsg, ping_v4_sendmsg
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>
Diffstat (limited to 'net')
-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 05e47d777009..56a010622f70 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -775,8 +775,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
775 ipc.addr = faddr = daddr; 775 ipc.addr = faddr = daddr;
776 776
777 if (ipc.opt && ipc.opt->opt.srr) { 777 if (ipc.opt && ipc.opt->opt.srr) {
778 if (!daddr) 778 if (!daddr) {
779 return -EINVAL; 779 err = -EINVAL;
780 goto out_free;
781 }
780 faddr = ipc.opt->opt.faddr; 782 faddr = ipc.opt->opt.faddr;
781 } 783 }
782 tos = get_rttos(&ipc, inet); 784 tos = get_rttos(&ipc, inet);
@@ -842,6 +844,7 @@ back_from_confirm:
842 844
843out: 845out:
844 ip_rt_put(rt); 846 ip_rt_put(rt);
847out_free:
845 if (free) 848 if (free)
846 kfree(ipc.opt); 849 kfree(ipc.opt);
847 if (!err) { 850 if (!err) {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c2a292dfd137..b61a770884fa 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -952,8 +952,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
952 sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); 952 sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags);
953 953
954 if (ipc.opt && ipc.opt->opt.srr) { 954 if (ipc.opt && ipc.opt->opt.srr) {
955 if (!daddr) 955 if (!daddr) {
956 return -EINVAL; 956 err = -EINVAL;
957 goto out_free;
958 }
957 faddr = ipc.opt->opt.faddr; 959 faddr = ipc.opt->opt.faddr;
958 connected = 0; 960 connected = 0;
959 } 961 }
@@ -1074,6 +1076,7 @@ do_append_data:
1074 1076
1075out: 1077out:
1076 ip_rt_put(rt); 1078 ip_rt_put(rt);
1079out_free:
1077 if (free) 1080 if (free)
1078 kfree(ipc.opt); 1081 kfree(ipc.opt);
1079 if (!err) 1082 if (!err)