Commit d664986f authored by Andrey Ignatov's avatar Andrey Ignatov Committed by Greg Kroah-Hartman

ipv4: fix memory leaks in udp_sendmsg, ping_v4_sendmsg

[ Upstream commit 1b97013b ]

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

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

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: c319b4d7 (net: ipv4: add IPPROTO_ICMP socket kind)
Signed-off-by: default avatarAndrey Ignatov <rdna@fb.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent aef419ef
...@@ -775,8 +775,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -775,8 +775,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
ipc.addr = faddr = daddr; ipc.addr = faddr = daddr;
if (ipc.opt && ipc.opt->opt.srr) { if (ipc.opt && ipc.opt->opt.srr) {
if (!daddr) if (!daddr) {
return -EINVAL; err = -EINVAL;
goto out_free;
}
faddr = ipc.opt->opt.faddr; faddr = ipc.opt->opt.faddr;
} }
tos = get_rttos(&ipc, inet); tos = get_rttos(&ipc, inet);
...@@ -841,6 +843,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -841,6 +843,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
out: out:
ip_rt_put(rt); ip_rt_put(rt);
out_free:
if (free) if (free)
kfree(ipc.opt); kfree(ipc.opt);
if (!err) { if (!err) {
......
...@@ -982,8 +982,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -982,8 +982,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags);
if (ipc.opt && ipc.opt->opt.srr) { if (ipc.opt && ipc.opt->opt.srr) {
if (!daddr) if (!daddr) {
return -EINVAL; err = -EINVAL;
goto out_free;
}
faddr = ipc.opt->opt.faddr; faddr = ipc.opt->opt.faddr;
connected = 0; connected = 0;
} }
...@@ -1090,6 +1092,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1090,6 +1092,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
out: out:
ip_rt_put(rt); ip_rt_put(rt);
out_free:
if (free) if (free)
kfree(ipc.opt); kfree(ipc.opt);
if (!err) if (!err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment