Skip to content

Commit bae1b97

Browse files
author
CKI KWF Bot
committed
Merge: tls: stable backport for 10.2 phase 1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1528 JIRA: https://issues.redhat.com/browse/RHEL-115592 * 54a3eca bpf: fix ktls panic with sockmap * 79f0c39 ktls, sockmap: Fix missing uncharge operation * 491deb9 net/tls: fix kernel panic when alloc_page failed * 178f6a5 bpf, ktls: Fix data corruption when using bpf_msg_pop_data() in ktls * 6db015f tls: handle data disappearing from under the TLS ULP * d7e8259 selftests: tls: test TCP stealing data from under the TLS socket * 715c7a3 selftests: tls: make the new data_steal test less flaky * 0aeb54a tls: make sure to abort the stream if headers are bogus * 4c05c7e selftests: tls: test skb copy under mem pressure and OOB Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com> --- <small>Created 2025-10-02 10:32 UTC by backporter - [KWF FAQ](https://red.ht/kernel_workflow_doc) - [Slack #team-kernel-workflow](https://redhat-internal.slack.com/archives/C04LRUPMJQ5) - [Source](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/webhook/utils/backporter.py) - [Documentation](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/docs/README.backporter.md) - [Report an issue](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12334433&issuetype=1&priority=4&summary=backporter+webhook+issue&components=kernel-workflow+/+backporter)</small> Approved-by: Hangbin Liu <haliu@redhat.com> Approved-by: Xin Long <lxin@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 8bd3933 + 0a3e6e6 commit bae1b97

File tree

4 files changed

+127
-15
lines changed

4 files changed

+127
-15
lines changed

net/tls/tls.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ void update_sk_prot(struct sock *sk, struct tls_context *ctx);
141141

142142
int wait_on_pending_writer(struct sock *sk, long *timeo);
143143
void tls_err_abort(struct sock *sk, int err);
144+
void tls_strp_abort_strp(struct tls_strparser *strp, int err);
144145

145146
int init_prot_info(struct tls_prot_info *prot,
146147
const struct tls_crypto_info *crypto_info,
@@ -196,7 +197,7 @@ void tls_strp_msg_done(struct tls_strparser *strp);
196197
int tls_rx_msg_size(struct tls_strparser *strp, struct sk_buff *skb);
197198
void tls_rx_msg_ready(struct tls_strparser *strp);
198199

199-
void tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh);
200+
bool tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh);
200201
int tls_strp_msg_cow(struct tls_sw_context_rx *ctx);
201202
struct sk_buff *tls_strp_msg_detach(struct tls_sw_context_rx *ctx);
202203
int tls_strp_msg_hold(struct tls_strparser *strp, struct sk_buff_head *dst);

net/tls/tls_strp.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
static struct workqueue_struct *tls_strp_wq;
1515

16-
static void tls_strp_abort_strp(struct tls_strparser *strp, int err)
16+
void tls_strp_abort_strp(struct tls_strparser *strp, int err)
1717
{
1818
if (strp->stopped)
1919
return;
@@ -211,11 +211,17 @@ static int tls_strp_copyin_frag(struct tls_strparser *strp, struct sk_buff *skb,
211211
struct sk_buff *in_skb, unsigned int offset,
212212
size_t in_len)
213213
{
214+
unsigned int nfrag = skb->len / PAGE_SIZE;
214215
size_t len, chunk;
215216
skb_frag_t *frag;
216217
int sz;
217218

218-
frag = &skb_shinfo(skb)->frags[skb->len / PAGE_SIZE];
219+
if (unlikely(nfrag >= skb_shinfo(skb)->nr_frags)) {
220+
DEBUG_NET_WARN_ON_ONCE(1);
221+
return -EMSGSIZE;
222+
}
223+
224+
frag = &skb_shinfo(skb)->frags[nfrag];
219225

220226
len = in_len;
221227
/* First make sure we got the header */
@@ -396,7 +402,6 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
396402
return 0;
397403

398404
shinfo = skb_shinfo(strp->anchor);
399-
shinfo->frag_list = NULL;
400405

401406
/* If we don't know the length go max plus page for cipher overhead */
402407
need_spc = strp->stm.full_len ?: TLS_MAX_PAYLOAD_SIZE + PAGE_SIZE;
@@ -412,6 +417,8 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
412417
page, 0, 0);
413418
}
414419

420+
shinfo->frag_list = NULL;
421+
415422
strp->copy_mode = 1;
416423
strp->stm.offset = 0;
417424

@@ -474,7 +481,7 @@ static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
474481
strp->stm.offset = offset;
475482
}
476483

477-
void tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
484+
bool tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
478485
{
479486
struct strp_msg *rxm;
480487
struct tls_msg *tlm;
@@ -483,8 +490,11 @@ void tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
483490
DEBUG_NET_WARN_ON_ONCE(!strp->stm.full_len);
484491

485492
if (!strp->copy_mode && force_refresh) {
486-
if (WARN_ON(tcp_inq(strp->sk) < strp->stm.full_len))
487-
return;
493+
if (unlikely(tcp_inq(strp->sk) < strp->stm.full_len)) {
494+
WRITE_ONCE(strp->msg_ready, 0);
495+
memset(&strp->stm, 0, sizeof(strp->stm));
496+
return false;
497+
}
488498

489499
tls_strp_load_anchor_with_queue(strp, strp->stm.full_len);
490500
}
@@ -494,6 +504,8 @@ void tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
494504
rxm->offset = strp->stm.offset;
495505
tlm = tls_msg(strp->anchor);
496506
tlm->control = strp->mark;
507+
508+
return true;
497509
}
498510

499511
/* Called with lock held on lower socket */
@@ -514,10 +526,8 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
514526
tls_strp_load_anchor_with_queue(strp, inq);
515527
if (!strp->stm.full_len) {
516528
sz = tls_rx_msg_size(strp, strp->anchor);
517-
if (sz < 0) {
518-
tls_strp_abort_strp(strp, sz);
529+
if (sz < 0)
519530
return sz;
520-
}
521531

522532
strp->stm.full_len = sz;
523533

net/tls/tls_sw.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,19 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
872872
delta = msg->sg.size;
873873
psock->eval = sk_psock_msg_verdict(sk, psock, msg);
874874
delta -= msg->sg.size;
875+
876+
if ((s32)delta > 0) {
877+
/* It indicates that we executed bpf_msg_pop_data(),
878+
* causing the plaintext data size to decrease.
879+
* Therefore the encrypted data size also needs to
880+
* correspondingly decrease. We only need to subtract
881+
* delta to calculate the new ciphertext length since
882+
* ktls does not support block encryption.
883+
*/
884+
struct sk_msg *enc = &ctx->open_rec->msg_encrypted;
885+
886+
sk_msg_trim(sk, enc, enc->sg.size - delta);
887+
}
875888
}
876889
if (msg->cork_bytes && msg->cork_bytes > msg->sg.size &&
877890
!enospc && !full_record) {
@@ -908,6 +921,13 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
908921
&msg_redir, send, flags);
909922
lock_sock(sk);
910923
if (err < 0) {
924+
/* Regardless of whether the data represented by
925+
* msg_redir is sent successfully, we have already
926+
* uncharged it via sk_msg_return_zero(). The
927+
* msg->sg.size represents the remaining unprocessed
928+
* data, which needs to be uncharged here.
929+
*/
930+
sk_mem_uncharge(sk, msg->sg.size);
911931
*copied -= sk_msg_free_nocharge(sk, &msg_redir);
912932
msg->sg.size = 0;
913933
}
@@ -1120,9 +1140,13 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
11201140
num_async++;
11211141
else if (ret == -ENOMEM)
11221142
goto wait_for_memory;
1123-
else if (ctx->open_rec && ret == -ENOSPC)
1143+
else if (ctx->open_rec && ret == -ENOSPC) {
1144+
if (msg_pl->cork_bytes) {
1145+
ret = 0;
1146+
goto send_end;
1147+
}
11241148
goto rollback_iter;
1125-
else if (ret != -EAGAIN)
1149+
} else if (ret != -EAGAIN)
11261150
goto send_end;
11271151
}
11281152
continue;
@@ -1360,7 +1384,8 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock,
13601384
return sock_intr_errno(timeo);
13611385
}
13621386

1363-
tls_strp_msg_load(&ctx->strp, released);
1387+
if (unlikely(!tls_strp_msg_load(&ctx->strp, released)))
1388+
return tls_rx_rec_wait(sk, psock, nonblock, false);
13641389

13651390
return 1;
13661391
}
@@ -2449,8 +2474,7 @@ int tls_rx_msg_size(struct tls_strparser *strp, struct sk_buff *skb)
24492474
return data_len + TLS_HEADER_SIZE;
24502475

24512476
read_failure:
2452-
tls_err_abort(strp->sk, ret);
2453-
2477+
tls_strp_abort_strp(strp, ret);
24542478
return ret;
24552479
}
24562480

tools/testing/selftests/net/tls.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2770,6 +2770,22 @@ TEST_F(tls_err, poll_partial_rec_async)
27702770
}
27712771
}
27722772

2773+
/* Use OOB+large send to trigger copy mode due to memory pressure.
2774+
* OOB causes a short read.
2775+
*/
2776+
TEST_F(tls_err, oob_pressure)
2777+
{
2778+
char buf[1<<16];
2779+
int i;
2780+
2781+
memrnd(buf, sizeof(buf));
2782+
2783+
EXPECT_EQ(send(self->fd2, buf, 5, MSG_OOB), 5);
2784+
EXPECT_EQ(send(self->fd2, buf, sizeof(buf), 0), sizeof(buf));
2785+
for (i = 0; i < 64; i++)
2786+
EXPECT_EQ(send(self->fd2, buf, 5, MSG_OOB), 5);
2787+
}
2788+
27732789
TEST(non_established) {
27742790
struct tls12_crypto_info_aes_gcm_256 tls12;
27752791
struct sockaddr_in addr;
@@ -2998,6 +3014,67 @@ TEST(prequeue) {
29983014
close(cfd);
29993015
}
30003016

3017+
TEST(data_steal) {
3018+
struct tls_crypto_info_keys tls;
3019+
char buf[20000], buf2[20000];
3020+
struct sockaddr_in addr;
3021+
int sfd, cfd, ret, fd;
3022+
int pid, status;
3023+
socklen_t len;
3024+
3025+
len = sizeof(addr);
3026+
memrnd(buf, sizeof(buf));
3027+
3028+
tls_crypto_info_init(TLS_1_2_VERSION, TLS_CIPHER_AES_GCM_256, &tls, 0);
3029+
3030+
addr.sin_family = AF_INET;
3031+
addr.sin_addr.s_addr = htonl(INADDR_ANY);
3032+
addr.sin_port = 0;
3033+
3034+
fd = socket(AF_INET, SOCK_STREAM, 0);
3035+
sfd = socket(AF_INET, SOCK_STREAM, 0);
3036+
3037+
ASSERT_EQ(bind(sfd, &addr, sizeof(addr)), 0);
3038+
ASSERT_EQ(listen(sfd, 10), 0);
3039+
ASSERT_EQ(getsockname(sfd, &addr, &len), 0);
3040+
ASSERT_EQ(connect(fd, &addr, sizeof(addr)), 0);
3041+
ASSERT_GE(cfd = accept(sfd, &addr, &len), 0);
3042+
close(sfd);
3043+
3044+
ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
3045+
if (ret) {
3046+
ASSERT_EQ(errno, ENOENT);
3047+
SKIP(return, "no TLS support");
3048+
}
3049+
ASSERT_EQ(setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls")), 0);
3050+
3051+
/* Spawn a child and get it into the read wait path of the underlying
3052+
* TCP socket.
3053+
*/
3054+
pid = fork();
3055+
ASSERT_GE(pid, 0);
3056+
if (!pid) {
3057+
EXPECT_EQ(recv(cfd, buf, sizeof(buf) / 2, MSG_WAITALL),
3058+
sizeof(buf) / 2);
3059+
exit(!__test_passed(_metadata));
3060+
}
3061+
3062+
usleep(10000);
3063+
ASSERT_EQ(setsockopt(fd, SOL_TLS, TLS_TX, &tls, tls.len), 0);
3064+
ASSERT_EQ(setsockopt(cfd, SOL_TLS, TLS_RX, &tls, tls.len), 0);
3065+
3066+
EXPECT_EQ(send(fd, buf, sizeof(buf), 0), sizeof(buf));
3067+
EXPECT_EQ(wait(&status), pid);
3068+
EXPECT_EQ(status, 0);
3069+
EXPECT_EQ(recv(cfd, buf2, sizeof(buf2), MSG_DONTWAIT), -1);
3070+
/* Don't check errno, the error will be different depending
3071+
* on what random bytes TLS interpreted as the record length.
3072+
*/
3073+
3074+
close(fd);
3075+
close(cfd);
3076+
}
3077+
30013078
static void __attribute__((constructor)) fips_check(void) {
30023079
int res;
30033080
FILE *f;

0 commit comments

Comments
 (0)