mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 15:43:08 -04:00
Merge branch 'tls-fix-plaintext-sk_msg-ring-over-fill'
chanyoung says:
====================
tls: fix plaintext sk_msg ring over-fill
An unprivileged user can oops the kernel by splicing into a kTLS socket
whose open record already has a full plaintext sk_msg ring. Reproduced on
net (53658c6f36) with a stock config, no KASAN.
Patch 2 oopses an unpatched kernel and passes with patch 1 applied.
====================
Link: https://patch.msgid.link/20260804052837.49015-1-ppoo1220@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -832,6 +832,14 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
|
||||
if (!sk_stream_memory_free(sk))
|
||||
goto wait_for_sndbuf;
|
||||
|
||||
/* open record may be full if we couldn't push it in the last sendmsg call */
|
||||
if (sk_msg_full(msg_pl)) {
|
||||
full_record = true;
|
||||
sk_msg_trim(sk, msg_en,
|
||||
msg_pl->sg.size + prot->overhead_size);
|
||||
goto copied;
|
||||
}
|
||||
|
||||
alloc_encrypted:
|
||||
ret = tls_alloc_encrypted_msg(sk, required_size);
|
||||
if (ret) {
|
||||
@@ -921,6 +929,12 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
|
||||
msg_pl, try_to_copy);
|
||||
if (ret < 0)
|
||||
goto trim_sgl;
|
||||
|
||||
if (sk_msg_full(msg_pl)) {
|
||||
full_record = true;
|
||||
sk_msg_trim(sk, msg_en,
|
||||
msg_pl->sg.size + prot->overhead_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Open records defined only if successfully copied, otherwise
|
||||
|
||||
@@ -835,6 +835,43 @@ TEST_F(tls, send_and_splice)
|
||||
EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
|
||||
}
|
||||
|
||||
TEST_F(tls, splice_onto_full_record)
|
||||
{
|
||||
char mem_send[4608];
|
||||
char mem_recv[4608];
|
||||
int frag_len = 100;
|
||||
int nfrags, i, off;
|
||||
int p[2];
|
||||
|
||||
memrnd(mem_send, sizeof(mem_send));
|
||||
ASSERT_GE(pipe(p), 0);
|
||||
|
||||
for (nfrags = 16; nfrags <= 44; nfrags++) {
|
||||
for (i = 0, off = 0; i < nfrags; i++, off += frag_len) {
|
||||
EXPECT_EQ(write(p[1], mem_send + off, frag_len), frag_len);
|
||||
EXPECT_EQ(splice(p[0], NULL, self->fd, NULL, frag_len,
|
||||
SPLICE_F_MORE), frag_len);
|
||||
}
|
||||
|
||||
EXPECT_EQ(send(self->fd, mem_send + off, 1, MSG_MORE), 1);
|
||||
off++;
|
||||
|
||||
EXPECT_EQ(write(p[1], mem_send + off, frag_len), frag_len);
|
||||
EXPECT_EQ(splice(p[0], NULL, self->fd, NULL, frag_len,
|
||||
SPLICE_F_MORE), frag_len);
|
||||
off += frag_len;
|
||||
|
||||
EXPECT_EQ(send(self->fd, mem_send + off, 1, 0), 1);
|
||||
off++;
|
||||
|
||||
EXPECT_EQ(recv(self->cfd, mem_recv, off, MSG_WAITALL), off);
|
||||
EXPECT_EQ(memcmp(mem_send, mem_recv, off), 0);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
}
|
||||
|
||||
TEST_F(tls, splice_to_pipe)
|
||||
{
|
||||
int send_len = TLS_PAYLOAD_MAX_LEN;
|
||||
|
||||
Reference in New Issue
Block a user