summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@amazon.com>2023-09-11 19:27:53 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-09-19 12:20:30 +0200
commit2e18493c421428a936946c452461b8e979088f17 (patch)
tree3f93fcee42e934ec20fb88aeb36564df10680230
parent606a0d8ff67459e605550289132c4050e95b6eda (diff)
downloadlinux-stable-2e18493c421428a936946c452461b8e979088f17.tar.gz
linux-stable-2e18493c421428a936946c452461b8e979088f17.tar.bz2
linux-stable-2e18493c421428a936946c452461b8e979088f17.zip
kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg().
[ Upstream commit a22730b1b4bf437c6bbfdeff5feddf54be4aeada ] syzkaller found a memory leak in kcm_sendmsg(), and commit c821a88bd720 ("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: c821a88bd720 ("kcm: Fix memory leak in error path of kcm_sendmsg()") Fixes: ab7ac4eb9832 ("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--net/kcm/kcmsock.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index fb025406ea56..39b3c7fbf9f6 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -1064,17 +1064,18 @@ partial_message:
out_error:
kcm_push(kcm);
- if (copied && sock->type == SOCK_SEQPACKET) {
+ if (sock->type == SOCK_SEQPACKET) {
/* Wrote some bytes before encountering an
* error, return partial success.
*/
- goto partial_message;
- }
-
- if (head != kcm->seq_skb)
+ if (copied)
+ goto partial_message;
+ if (head != kcm->seq_skb)
+ kfree_skb(head);
+ } else {
kfree_skb(head);
- else if (copied)
- kcm_tx_msg(head)->last_skb = skb;
+ kcm->seq_skb = NULL;
+ }
err = sk_stream_error(sk, msg->msg_flags, err);