* [PATCH] net: geneve: gate GRO completion hints on socket config
@ 2026-06-07 1:34 Kyle Zeng
2026-06-07 1:35 ` Kyle Zeng
2026-06-08 9:30 ` Paolo Abeni
0 siblings, 2 replies; 3+ messages in thread
From: Kyle Zeng @ 2026-06-07 1:34 UTC (permalink / raw)
To: netdev; +Cc: Eric Dumazet, Kyle Zeng
Geneve GRO receive only consumes the netdev GRO hint option when the
receiving Geneve socket has gro_hint enabled. geneve_gro_complete(),
however, parses the hint option directly with geneve_opt_gro_hint_off()
and therefore extends the completion offset even for sockets that did not
enable hint processing.
That lets a packet for a normal Geneve socket carry a syntactically valid
hint with an attacker-controlled nested_hdr_len. GRO receive validates
and pulls only the ordinary Geneve header/options, but completion can then
run the inner protocol completion callback at nhoff + gh_len where gh_len
includes the untrusted hint length. This can make completion access beyond
the header area validated by receive.
Use geneve_sk_gro_hint_off() in the completion path, matching receive and
post-decap processing, so the hint is honored only for sockets that enabled
the feature.
Fixes: fd0dd796576e ("geneve: use GRO hint option in the RX path")
Signed-off-by: Kyle Zeng <kylebot@openai.com>
---
drivers/net/geneve.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index c6563367d382..d62cbee6c0fe 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -948,13 +948,13 @@ static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb,
struct genevehdr *gh;
struct packet_offload *ptype;
__be16 type;
- int gh_len;
+ unsigned int gh_len;
int err = -ENOSYS;
gh = (struct genevehdr *)(skb->data + nhoff);
gh_len = geneve_hlen(gh);
type = gh->proto_type;
- geneve_opt_gro_hint_off(gh, &type, &gh_len);
+ geneve_sk_gro_hint_off(sk, gh, &type, &gh_len);
/* since skb->encapsulation is set, eth_gro_complete() sets the inner mac header */
if (likely(type == htons(ETH_P_TEB)))
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] net: geneve: gate GRO completion hints on socket config
2026-06-07 1:34 [PATCH] net: geneve: gate GRO completion hints on socket config Kyle Zeng
@ 2026-06-07 1:35 ` Kyle Zeng
2026-06-08 9:30 ` Paolo Abeni
1 sibling, 0 replies; 3+ messages in thread
From: Kyle Zeng @ 2026-06-07 1:35 UTC (permalink / raw)
To: netdev; +Cc: Eric Dumazet
Hi,
We have a PoC that can trigger warning or KASAN report.
Please DM if you need it to reproduce the issue.
Thanks
Kyle
On Sat, Jun 6, 2026 at 6:34 PM Kyle Zeng <kylebot@openai.com> wrote:
>
> Geneve GRO receive only consumes the netdev GRO hint option when the
> receiving Geneve socket has gro_hint enabled. geneve_gro_complete(),
> however, parses the hint option directly with geneve_opt_gro_hint_off()
> and therefore extends the completion offset even for sockets that did not
> enable hint processing.
>
> That lets a packet for a normal Geneve socket carry a syntactically valid
> hint with an attacker-controlled nested_hdr_len. GRO receive validates
> and pulls only the ordinary Geneve header/options, but completion can then
> run the inner protocol completion callback at nhoff + gh_len where gh_len
> includes the untrusted hint length. This can make completion access beyond
> the header area validated by receive.
>
> Use geneve_sk_gro_hint_off() in the completion path, matching receive and
> post-decap processing, so the hint is honored only for sockets that enabled
> the feature.
>
> Fixes: fd0dd796576e ("geneve: use GRO hint option in the RX path")
> Signed-off-by: Kyle Zeng <kylebot@openai.com>
> ---
> drivers/net/geneve.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> index c6563367d382..d62cbee6c0fe 100644
> --- a/drivers/net/geneve.c
> +++ b/drivers/net/geneve.c
> @@ -948,13 +948,13 @@ static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb,
> struct genevehdr *gh;
> struct packet_offload *ptype;
> __be16 type;
> - int gh_len;
> + unsigned int gh_len;
> int err = -ENOSYS;
>
> gh = (struct genevehdr *)(skb->data + nhoff);
> gh_len = geneve_hlen(gh);
> type = gh->proto_type;
> - geneve_opt_gro_hint_off(gh, &type, &gh_len);
> + geneve_sk_gro_hint_off(sk, gh, &type, &gh_len);
>
> /* since skb->encapsulation is set, eth_gro_complete() sets the inner mac header */
> if (likely(type == htons(ETH_P_TEB)))
> --
> 2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] net: geneve: gate GRO completion hints on socket config
2026-06-07 1:34 [PATCH] net: geneve: gate GRO completion hints on socket config Kyle Zeng
2026-06-07 1:35 ` Kyle Zeng
@ 2026-06-08 9:30 ` Paolo Abeni
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Abeni @ 2026-06-08 9:30 UTC (permalink / raw)
To: Kyle Zeng, netdev; +Cc: Eric Dumazet
6/7/26 3:34 AM, Kyle Zeng wrote:
> Geneve GRO receive only consumes the netdev GRO hint option when the
> receiving Geneve socket has gro_hint enabled. geneve_gro_complete(),
> however, parses the hint option directly with geneve_opt_gro_hint_off()
> and therefore extends the completion offset even for sockets that did not
> enable hint processing.
>
> That lets a packet for a normal Geneve socket carry a syntactically valid
> hint with an attacker-controlled nested_hdr_len. GRO receive validates
> and pulls only the ordinary Geneve header/options, but completion can then
> run the inner protocol completion callback at nhoff + gh_len where gh_len
> includes the untrusted hint length. This can make completion access beyond
> the header area validated by receive.
>
> Use geneve_sk_gro_hint_off() in the completion path, matching receive and
> post-decap processing, so the hint is honored only for sockets that enabled
> the feature.
>
> Fixes: fd0dd796576e ("geneve: use GRO hint option in the RX path")
> Signed-off-by: Kyle Zeng <kylebot@openai.com>
> ---
> drivers/net/geneve.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> index c6563367d382..d62cbee6c0fe 100644
> --- a/drivers/net/geneve.c
> +++ b/drivers/net/geneve.c
> @@ -948,13 +948,13 @@ static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb,
> struct genevehdr *gh;
> struct packet_offload *ptype;
> __be16 type;
> - int gh_len;
> + unsigned int gh_len;
> int err = -ENOSYS;
>
> gh = (struct genevehdr *)(skb->data + nhoff);
> gh_len = geneve_hlen(gh);
> type = gh->proto_type;
> - geneve_opt_gro_hint_off(gh, &type, &gh_len);
> + geneve_sk_gro_hint_off(sk, gh, &type, &gh_len);
Sashiko noted that `geneve_sk_gro_hint_off` could race with
geneve_quiesce() (and thus with geneve_unquiesce()): gro_complete could
observe a different hint status WRT the gro_receive step.
I think you additionally need to validate the inner(most) network header
offset as derived by `geneve_sk_gro_hint_off()` (i.e. gh_len + nhoff +
eventual mac presence) vs the one computed by gro_receive (that is:
NAPI_GRO_CB(skb)->inner_network_offset), and ev. error out in case of
mismatch.
/P
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-08 9:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-07 1:34 [PATCH] net: geneve: gate GRO completion hints on socket config Kyle Zeng
2026-06-07 1:35 ` Kyle Zeng
2026-06-08 9:30 ` Paolo Abeni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox