From: Jakub Kicinski <kuba@kernel.org>
To: rjethwani@purestorage.com
Cc: Jakub Kicinski <kuba@kernel.org>,
netdev@vger.kernel.org, saeedm@nvidia.com, tariqt@nvidia.com,
mbloch@nvidia.com, borisp@nvidia.com, john.fastabend@gmail.com,
sd@queasysnail.net, davem@davemloft.net, pabeni@redhat.com,
edumazet@google.com, leon@kernel.org,
andrew.gospodarek@broadcom.com
Subject: Re: [PATCH v16 04/10] tls: add TLS 1.3 hardware offload support
Date: Mon, 17 Aug 2026 15:11:28 -0700 [thread overview]
Message-ID: <20260817221128.3666336-1-kuba@kernel.org> (raw)
In-Reply-To: <20260807183853.2288959-5-rjethwani@purestorage.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
tls: add TLS 1.3 hardware offload support
This drops the TLS_1_2_VERSION gates in tls_set_device_offload() and
tls_set_device_offload_rx(), teaches tls_device_record_close() to append
the TLS 1.3 content_type byte along with the tag, and switches the
device fallback encryption path to prot->prepend_size / prot->aad_size
so the 1.3 layouts work. tls_device_init() also pre-populates
dummy_page with an identity byte map.
A few questions below.
> diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
> index 37bb06a8e8f5..bbb1aa733500 100644
> --- a/net/tls/tls_device.c
> +++ b/net/tls/tls_device.c
> @@ -317,25 +317,34 @@ static void tls_device_record_close(struct sock *sk,
> unsigned char record_type)
> {
> struct tls_prot_info *prot = &ctx->prot_info;
> - struct page_frag dummy_tag_frag;
> -
> - /* append tag
> - * device will fill in the tag, we just need to append a placeholder
> - * use socket memory to improve coalescing (re-using a single buffer
> - * increases frag count)
> - * if we can't allocate memory now use the dummy page
> + int tail = prot->tag_size + prot->tail_size;
> +
> + /* Append tail: tag for TLS 1.2, content_type + tag for TLS 1.3.
> + * Device fills in the tag, we just need to append a placeholder.
> + * Use socket memory to improve coalescing (re-using a single buffer
> + * increases frag count); if allocation fails use dummy_page
> + * (offset = record_type gives correct content_type byte via
> + * identity mapping)
> */
> - if (unlikely(pfrag->size - pfrag->offset < prot->tag_size) &&
> - !skb_page_frag_refill(prot->tag_size, pfrag, sk->sk_allocation)) {
> - dummy_tag_frag.page = dummy_page;
> - dummy_tag_frag.offset = 0;
> - pfrag = &dummy_tag_frag;
> + if (unlikely(pfrag->size - pfrag->offset < tail) &&
> + !skb_page_frag_refill(tail, pfrag, sk->sk_allocation)) {
> + struct page_frag dummy_pfrag = {
> + .page = dummy_page,
> + .offset = record_type,
> + };
> + tls_append_frag(record, &dummy_pfrag, tail);
[Severity: Medium]
Here record_type is used directly as an offset into the shared global
dummy_page, and tail = prot->tag_size + prot->tail_size bytes are appended
starting from that offset. tls_device_init() only writes the first 256
bytes of the page, and the page comes from a plain alloc_page(GFP_KERNEL),
so the rest is not zeroed.
With AES-GCM (tag_size 16) and TLS 1.3 (tail_size 1), a record_type of 240
or above makes the appended frag cover dummy_page bytes
[256, record_type + 17), which are never initialized.
record_type is taken verbatim from the user cmsg; tls_process_cmsg() in
tls_main.c checks only cmsg_len and MSG_MORE:
case TLS_SET_RECORD_TYPE:
if (cmsg->cmsg_len < CMSG_LEN(sizeof(*record_type)))
return -EINVAL;
if (msg->msg_flags & MSG_MORE)
return -EINVAL;
...
*record_type = *(unsigned char *)CMSG_DATA(cmsg);
so all 256 offsets are reachable from an unprivileged process. Can this
put uninitialized page contents into the tag placeholder area of the
record? Would zeroing the page (__GFP_ZERO), initializing
256 + max tag bytes, or bounding the offset be preferable?
Related to this, the comment added in tls_device_init() says "By populating
all 256 values, we avoid needing to validate record_type at runtime", but
the identity map only covers the content_type byte, not the tag portion of
the tail that follows it.
> + } else {
> + if (prot->tail_size) {
> + char *content_type_addr = page_address(pfrag->page) +
> + pfrag->offset;
> + *content_type_addr = record_type;
> + }
> + tls_append_frag(record, pfrag, tail);
> }
> - tls_append_frag(record, pfrag, prot->tag_size);
[Severity: High]
This isn't a bug introduced by this patch, but the else branch now
dereferences pfrag->page one step earlier than before, and pfrag->page is
never checked for NULL.
Consider the state skb_page_frag_refill() leaves behind on failure in
net/core/sock.c:
pfrag->offset = 0;
...
pfrag->page = alloc_page(gfp);
if (likely(pfrag->page)) {
pfrag->size = PAGE_SIZE;
return true;
}
return false;
offset is zeroed and page is NULL, but size keeps its previous non-zero
value, so pfrag->size - pfrag->offset is at least PAGE_SIZE and the
"< tail" guard here is false. The dummy_page fallback is skipped and the
else branch runs.
Can tls_device_record_close() then be reached with that pfrag? In
tls_push_data(), with an already-open record (record->len >
prot->prepend_size, e.g. after a previous MSG_MORE sendmsg),
tls_do_allocation() takes the sk_page_frag_refill(sk, pfrag) path; on
allocation failure it returns -ENOMEM, sk_stream_wait_memory() returns
non-zero (immediately -EAGAIN for MSG_DONTWAIT), and control does:
} else if (record->len > prot->prepend_size) {
goto last_record;
}
which sets done = true and calls tls_device_record_close(sk, tls_ctx,
record, pfrag, record_type).
For TLS 1.3 (prot->tail_size == 1) that computes page_address(NULL) + 0 and
stores record_type through it, then tls_append_frag() does get_page(NULL).
The pre-patch code took the same false branch and crashed in
tls_append_frag(), so the NULL deref itself is older, but should this test
pfrag->page (or reset pfrag->size on refill failure) so the dummy_page
fallback that exists for exactly this situation is actually used?
>
> /* fill prepend */
> tls_fill_prepend(ctx, skb_frag_address(&record->frags[0]),
> - record->len - prot->overhead_size,
> + record->len - prot->overhead_size + prot->tail_size,
> record_type);
> }
>
[ ... ]
> @@ -1091,11 +1100,6 @@ int tls_set_device_offload(struct sock *sk)
> }
>
> crypto_info = &ctx->crypto_send.info;
> - if (crypto_info->version != TLS_1_2_VERSION) {
> - rc = -EOPNOTSUPP;
> - goto release_netdev;
> - }
> -
> cipher_desc = get_cipher_desc(crypto_info->cipher_type);
> if (!cipher_desc || !cipher_desc->offloadable) {
> rc = -EINVAL;
[Severity: Low]
Should Documentation/networking/tls-offload.rst be updated along with this?
Its Rekey section still says:
Offload does not currently support TLS 1.3, therefore key rotation
is not a concern for offloaded connections at this point.
Removing the version gates here and in tls_set_device_offload_rx() makes
the first half untrue, and the later patches in the series ("tls: device:
add TX KeyUpdate support", "tls: device: add RX KeyUpdate support") make
the second half untrue. No patch in the series touches that file, so the
sentence is still there at the end of the series.
>
> @@ -1410,12 +1411,22 @@ static struct notifier_block tls_dev_notifier = {
>
> int __init tls_device_init(void)
> {
> - int err;
> + unsigned char *page_addr;
> + int err, i;
>
> dummy_page = alloc_page(GFP_KERNEL);
> if (!dummy_page)
> return -ENOMEM;
>
> + /* Pre-populate dummy_page with identity mapping for all byte values.
> + * This is used as fallback for TLS 1.3 content type when memory
> + * allocation fails. By populating all 256 values, we avoid needing
> + * to validate record_type at runtime.
> + */
> + page_addr = page_address(dummy_page);
> + for (i = 0; i < 256; i++)
> + page_addr[i] = (unsigned char)i;
> +
> destruct_wq = alloc_workqueue("ktls_device_destruct", WQ_PERCPU, 0);
> if (!destruct_wq) {
> err = -ENOMEM;
--
pw-bot: cr
next prev parent reply other threads:[~2026-08-17 22:11 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 18:38 [PATCH net-next v16 00/10] tls: Add TLS 1.3 hardware offload support Rishikesh Jethwani
2026-08-07 18:38 ` [PATCH v16 01/10] net: tls: reject TLS 1.3 offload in chcr_ktls and nfp drivers Rishikesh Jethwani
2026-08-07 18:38 ` [PATCH v16 02/10] net/mlx5e: add TLS 1.3 hardware offload support Rishikesh Jethwani
2026-08-07 18:38 ` [PATCH v16 03/10] tls: reject rekey attempts on an existing HW-offloaded connection Rishikesh Jethwani
2026-08-07 18:38 ` [PATCH v16 04/10] tls: add TLS 1.3 hardware offload support Rishikesh Jethwani
2026-08-17 22:11 ` Jakub Kicinski [this message]
2026-08-07 18:38 ` [PATCH v16 05/10] tls: split tls_set_sw_offload into init and finalize stages Rishikesh Jethwani
2026-08-17 22:11 ` Jakub Kicinski
2026-08-07 18:38 ` [PATCH v16 06/10] tls: prep helpers and refactors for HW offload KeyUpdate Rishikesh Jethwani
2026-08-17 22:11 ` Jakub Kicinski
2026-08-07 18:38 ` [PATCH v16 07/10] tls: device: add TX KeyUpdate support Rishikesh Jethwani
2026-08-17 22:11 ` Jakub Kicinski
2026-08-07 18:38 ` [PATCH v16 08/10] tls: device: add RX " Rishikesh Jethwani
2026-08-17 22:11 ` Jakub Kicinski
2026-08-07 18:38 ` [PATCH v16 09/10] tls: device: add tracepoints for the KeyUpdate path Rishikesh Jethwani
2026-08-17 22:11 ` Jakub Kicinski
2026-08-07 18:38 ` [PATCH v16 10/10] selftests: net: add TLS hardware offload test Rishikesh Jethwani
2026-08-17 22:10 ` Jakub Kicinski
2026-08-17 22:11 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260817221128.3666336-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew.gospodarek@broadcom.com \
--cc=borisp@nvidia.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=john.fastabend@gmail.com \
--cc=leon@kernel.org \
--cc=mbloch@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rjethwani@purestorage.com \
--cc=saeedm@nvidia.com \
--cc=sd@queasysnail.net \
--cc=tariqt@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.