From: Paolo Abeni <pabeni@redhat.com>
To: lucien.xin@gmail.com
Cc: netdev@vger.kernel.org, quic@lists.linux.dev,
davem@davemloft.net, kuba@kernel.org, edumazet@google.com,
pabeni@redhat.com, horms@kernel.org, metze@samba.org,
mbuhl@openbsd.org, tfanelli@redhat.com, hepengtao@xiaomi.com,
dreibh@simula.no, linux-cifs@vger.kernel.org, smfrench@gmail.com,
linkinjeon@kernel.org, tom@talpey.com,
kernel-tls-handshake@lists.linux.dev, chuck.lever@oracle.com,
jlayton@kernel.org, steved@redhat.com, hare@suse.de,
aahringo@redhat.com, dhowells@redhat.com, matttbe@kernel.org,
mail@johnericson.me, xiyou.wangcong@gmail.com,
alibuda@linux.alibaba.com, jbaron@akamai.com,
illiliti@protonmail.com, sd@queasysnail.net,
marcelo.leitner@gmail.com, daniel@haxx.se,
andrew.gospodarek@broadcom.com, mef@scarletmail.rutgers.edu,
paul@jakma.org
Subject: Re: [PATCH net-next v13 15/15] quic: add packet parser base
Date: Thu, 11 Jun 2026 10:20:08 +0200 [thread overview]
Message-ID: <20260611082008.138377-1-pabeni@redhat.com> (raw)
In-Reply-To: <0b03854cabaac243a0cdf42375c66cd033750bd0.1780855297.git.lucien.xin@gmail.com>
From: AI Reviewer <ai@example.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.
Full review at: https://netdev-ai.bots.linux.dev/sashiko/
---
quic: add packet parser base
This patch adds the QUIC packet RX parser, including ALPN extraction
from the Client Initial to demux to the right listener, an ICMP-driven
PMTU update path, and a per-net backlog/work for deferred parsing.
> diff --git a/net/quic/packet.c b/net/quic/packet.c
> index ba5204aceda6..430fc06d0012 100644
> --- a/net/quic/packet.c
> +++ b/net/quic/packet.c
[ ... ]
> +static int quic_packet_get_alpn(struct quic_data *alpn, u8 *p, u32 len)
> +{
> + int err = -EINVAL, found = 0, exts = 0;
> + u64 length, type;
> +
[ ... ]
> + while (len >= 4) { /* Scan extensions for ALPN (TLS_EXT_alpn). */
> + if (!quic_get_int(&p, &len, &type, 2))
> + break;
> + if (!quic_get_int(&p, &len, &length, 2))
> + break;
> + if (len < (u32)length) /* Incomplete TLS extensions. */
> + return 0;
[Medium]
Should this branch be treated as a parse failure rather than a success?
The other length-bound checks in this same function return err (-EINVAL)
when a declared length exceeds the remaining buffer, but this one returns
0 without populating alpn. The callers initialise alpn as
struct quic_data alpns = {};
and quic_listen_sock_lookup() then takes the no-ALPN branch:
if (!alpns->len) { /* No ALPNs or parse failed */
sk_nulls_for_each_rcu(tmp, node, &head->head) {
...
if (... && (!alpns->data || !quic_alpn(tmp)->len)) {
Because alpns->data is still NULL, the match collapses to true and any
listener bound to the address/port will match, including ones that
registered a specific ALPN list. Can a peer reach an ALPN-restricted
listener by sending a Client Initial with one extension whose declared
length is larger than what is left in the ClientHello?
Would returning err here (or always assigning alpn->data before
returning) match the comment in quic_listen_sock_lookup() that
distinguishes "TLS parsing succeeded but no ALPN was found" from "parse
failed"?
> + if (type == TLS_EXT_alpn) { /* Found ALPN extension. */
> + if (length > QUIC_ALPN_MAX_LEN)
> + return err;
> + len = length;
> + found = 1;
> + break;
> + }
> + /* Skip non-ALPN extensions. */
> + p += length;
> + len -= length;
> + if (exts++ >= TLS_MAX_EXTENSIONS)
> + return err;
[Low]
Is the post-increment intended here? With TLS_MAX_EXTENSIONS == 128, the
check (exts++ >= 128) first becomes true when exts has already reached
129, so 129 extensions are consumed before bail-out even though the
constant name suggests a cap of 128. Would
if (++exts > TLS_MAX_EXTENSIONS)
return err;
(or moving the check to the loop top) better reflect the intended limit?
> + }
[ ... ]
> +static int quic_packet_parse_alpn(struct sk_buff *skb, struct quic_data *alpn)
[ ... ]
> diff --git a/net/quic/socket.c b/net/quic/socket.c
> index 8f348d7c678b..19b164baf55d 100644
> --- a/net/quic/socket.c
> +++ b/net/quic/socket.c
[ ... ]
> +struct sock *quic_sock_lookup(struct sk_buff *skb, union quic_addr *sa,
> + union quic_addr *da, struct sock *usk,
> + struct quic_conn_id *dcid)
> +{
[ ... ]
> + rcu_read_lock();
> +begin:
> + sk_nulls_for_each_rcu(tmp, node, &head->head) {
> + if (net != sock_net(tmp))
> + continue;
> + paths = quic_paths(tmp);
> + odcid = quic_path_orig_dcid(paths);
> + if (quic_cmp_sk_addr(tmp, quic_path_saddr(paths, 0), sa) &&
> + quic_cmp_sk_addr(tmp, quic_path_daddr(paths, 0), da) &&
> + quic_path_usock(paths, 0) == usk &&
> + (!dcid || !quic_conn_id_cmp(odcid, dcid))) {
> + sk = tmp;
> + break;
> + }
> + }
[High]
Is the sk memory itself RCU-protected here? sk_nulls_for_each_rcu()
dereferences fields of tmp (sock_net(tmp), quic_paths(tmp),
quic_path_saddr(...), etc.) before any reference is taken. That is only
safe when the sk allocation is freed via RCU.
quic_init_sock() does not call sock_set_flag(sk, SOCK_RCU_FREE), and
neither quic_prot nor quicv6_prot sets slab_flags to SLAB_TYPESAFE_BY_RCU,
so sk_destruct() (and quic_sock_destruct()) runs synchronously on the
last sock_put(). Can a parallel close on tmp free the sock between
sk_nulls_for_each_rcu() exposing it and the field dereferences above?
The same shape appears in quic_listen_sock_lookup() further down, where
quic_alpn(tmp)->len is read inside the RCU walk before
refcount_inc_not_zero().
> + if (sk && unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
> + sk = NULL;
> + rcu_read_unlock();
> + return sk;
> +}
[ ... ]
> +struct sock *quic_listen_sock_lookup(struct sk_buff *skb, union quic_addr *sa,
> + union quic_addr *da,
> + struct quic_data *alpns)
> +{
[ ... ]
> + rcu_read_lock();
> + if (!alpns->len) { /* No ALPNs or parse failed */
> + sk_nulls_for_each_rcu(tmp, node, &head->head) {
[ ... ]
> + a = quic_path_saddr(quic_paths(tmp), 0);
> + if (net == sock_net(tmp) &&
> + quic_cmp_sk_addr(tmp, a, sa) &&
> + quic_path_usock(quic_paths(tmp), 0) == skb->sk &&
> + (!alpns->data || !quic_alpn(tmp)->len)) {
[ ... ]
> @@ -48,6 +196,9 @@ static void quic_sock_destruct(struct sock *sk)
> for (i = 0; i < QUIC_CRYPTO_MAX; i++)
> quic_crypto_free(quic_crypto(sk, i));
>
> + /* Deferred ALPN free for RCU readers in quic_listen_sock_lookup(). */
> + quic_data_free(quic_alpn(sk));
> +
Without SOCK_RCU_FREE or SLAB_TYPESAFE_BY_RCU on quic_prot/quicv6_prot,
does moving the alpn free into the destruct callback actually defer it
past an RCU grace period? quic_sock_destruct() is invoked from
sk_destruct() on the final sock_put() and is not itself an RCU callback,
so the comment's "Deferred ALPN free for RCU readers" assumption seems to
rely on a guarantee that is not configured on this protocol. Should this
patch also set sock_set_flag(sk, SOCK_RCU_FREE) in quic_init_sock(), or
alternatively take refcount_inc_not_zero() in the lookup helpers before
touching any fields of tmp?
> quic_sk_destruct(sk);
> }
>
[ ... ]
--
This is an AI-generated review.
prev parent reply other threads:[~2026-06-11 8:20 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-07 18:01 [PATCH net-next v13 00/15] net: introduce QUIC infrastructure and core subcomponents Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 01/15] net: define IPPROTO_QUIC and SOL_QUIC constants Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 02/15] net: build socket infrastructure for QUIC protocol Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 03/15] quic: provide common utilities and data structures Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 04/15] quic: provide family ops for address and protocol Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 05/15] quic: provide quic.h header files for kernel and userspace Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 06/15] quic: add stream management Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 07/15] quic: add connection id management Xin Long
2026-06-11 8:19 ` Paolo Abeni
2026-06-07 18:01 ` [PATCH net-next v13 08/15] quic: add path management Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 09/15] quic: add congestion control Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 10/15] quic: add packet number space Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 11/15] quic: add crypto key derivation and installation Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 12/15] quic: add crypto packet encryption and decryption Xin Long
2026-06-11 8:19 ` Paolo Abeni
2026-06-07 18:01 ` [PATCH net-next v13 13/15] quic: add timer management Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 14/15] quic: add packet builder base Xin Long
2026-06-07 18:01 ` [PATCH net-next v13 15/15] quic: add packet parser base Xin Long
2026-06-11 8:20 ` Paolo Abeni [this message]
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=20260611082008.138377-1-pabeni@redhat.com \
--to=pabeni@redhat.com \
--cc=aahringo@redhat.com \
--cc=alibuda@linux.alibaba.com \
--cc=andrew.gospodarek@broadcom.com \
--cc=chuck.lever@oracle.com \
--cc=daniel@haxx.se \
--cc=davem@davemloft.net \
--cc=dhowells@redhat.com \
--cc=dreibh@simula.no \
--cc=edumazet@google.com \
--cc=hare@suse.de \
--cc=hepengtao@xiaomi.com \
--cc=horms@kernel.org \
--cc=illiliti@protonmail.com \
--cc=jbaron@akamai.com \
--cc=jlayton@kernel.org \
--cc=kernel-tls-handshake@lists.linux.dev \
--cc=kuba@kernel.org \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=lucien.xin@gmail.com \
--cc=mail@johnericson.me \
--cc=marcelo.leitner@gmail.com \
--cc=matttbe@kernel.org \
--cc=mbuhl@openbsd.org \
--cc=mef@scarletmail.rutgers.edu \
--cc=metze@samba.org \
--cc=netdev@vger.kernel.org \
--cc=paul@jakma.org \
--cc=quic@lists.linux.dev \
--cc=sd@queasysnail.net \
--cc=smfrench@gmail.com \
--cc=steved@redhat.com \
--cc=tfanelli@redhat.com \
--cc=tom@talpey.com \
--cc=xiyou.wangcong@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox