Skip to content

Commit 9194830

Browse files
edumazetdavem330
authored andcommitted
ipv4: fix memory leaks in ip_cmsg_send() callers
Dmitry reported memory leaks of IP options allocated in ip_cmsg_send() when/if this function returns an error. Callers are responsible for the freeing. Many thanks to Dmitry for the report and diagnostic. Reported-by: Dmitry Vyukov <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c2bb7bc commit 9194830

File tree

4 files changed

+11
-3
lines changed

4 files changed

+11
-3
lines changed

net/ipv4/ip_sockglue.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
249249
switch (cmsg->cmsg_type) {
250250
case IP_RETOPTS:
251251
err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
252+
253+
/* Our caller is responsible for freeing ipc->opt */
252254
err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
253255
err < 40 ? err : 40);
254256
if (err)

net/ipv4/ping.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,8 +746,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
746746

747747
if (msg->msg_controllen) {
748748
err = ip_cmsg_send(sock_net(sk), msg, &ipc, false);
749-
if (err)
749+
if (unlikely(err)) {
750+
kfree(ipc.opt);
750751
return err;
752+
}
751753
if (ipc.opt)
752754
free = 1;
753755
}

net/ipv4/raw.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,10 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
547547

548548
if (msg->msg_controllen) {
549549
err = ip_cmsg_send(net, msg, &ipc, false);
550-
if (err)
550+
if (unlikely(err)) {
551+
kfree(ipc.opt);
551552
goto out;
553+
}
552554
if (ipc.opt)
553555
free = 1;
554556
}

net/ipv4/udp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1048,8 +1048,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
10481048
if (msg->msg_controllen) {
10491049
err = ip_cmsg_send(sock_net(sk), msg, &ipc,
10501050
sk->sk_family == AF_INET6);
1051-
if (err)
1051+
if (unlikely(err)) {
1052+
kfree(ipc.opt);
10521053
return err;
1054+
}
10531055
if (ipc.opt)
10541056
free = 1;
10551057
connected = 0;

0 commit comments

Comments
 (0)