Skip to content

Commit a22730b

Browse files
q2venPaolo Abeni
authored andcommitted
kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg().
syzkaller found a memory leak in kcm_sendmsg(), and commit c821a88 ("kcm: Fix memory leak in error path of kcm_sendmsg()") suppressed it by updating kcm_tx_msg(head)->last_skb if partial data is copied so that the following sendmsg() will resume from the skb. However, we cannot know how many bytes were copied when we get the error. Thus, we could mess up the MSG_MORE queue. When kcm_sendmsg() fails for SOCK_DGRAM, we should purge the queue as we do so for UDP by udp_flush_pending_frames(). Even without this change, when the error occurred, the following sendmsg() resumed from a wrong skb and the queue was messed up. However, we have yet to get such a report, and only syzkaller stumbled on it. So, this can be changed safely. Note this does not change SOCK_SEQPACKET behaviour. Fixes: c821a88 ("kcm: Fix memory leak in error path of kcm_sendmsg()") Fixes: ab7ac4e ("kcm: Kernel Connection Multiplexor module") Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://lore.kernel.org/r/20230912022753.33327-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 96f7dc6 commit a22730b

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

net/kcm/kcmsock.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -930,17 +930,18 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
930930
out_error:
931931
kcm_push(kcm);
932932

933-
if (copied && sock->type == SOCK_SEQPACKET) {
933+
if (sock->type == SOCK_SEQPACKET) {
934934
/* Wrote some bytes before encountering an
935935
* error, return partial success.
936936
*/
937-
goto partial_message;
938-
}
939-
940-
if (head != kcm->seq_skb)
937+
if (copied)
938+
goto partial_message;
939+
if (head != kcm->seq_skb)
940+
kfree_skb(head);
941+
} else {
941942
kfree_skb(head);
942-
else if (copied)
943-
kcm_tx_msg(head)->last_skb = skb;
943+
kcm->seq_skb = NULL;
944+
}
944945

945946
err = sk_stream_error(sk, msg->msg_flags, err);
946947

0 commit comments

Comments
 (0)