Re: [PATCH] inet: frags: invalidate queues before flushing them
From: Eric Dumazet
Date: Thu Sep 03 2026 - 11:38:54 EST
On Thu, Sep 3, 2026 at 4:12 PM Yilin Zhang <yilinzhang@xxxxxxxxxxx> wrote:
>
> fqdir_pre_exit() flushes the skbs from incomplete queues without
> changing their completion state. A fragment which found a queue before
> high_thresh was cleared can then acquire the queue lock and reuse stale
> reassembly metadata.
>
> For IPv6, this can make ip6_frag_reasm() use the old nhoffset with a
> new skb and access memory out of bounds. The resulting heap corruption
> can be leveraged for local privilege escalation when unprivileged
> network namespaces are available.
>
> Kill each queue before flushing it in fqdir_pre_exit(). This marks the
> queue complete and releases any timer reference removed by
> inet_frag_kill(), while leaving the hash reference for the asynchronous
> fqdir teardown. In-flight fragments consequently take the existing
> complete-queue drop path without changing the reusable-queue semantics
> of inet_frag_queue_flush().
>
> Fixes: 006a5035b495 ("inet: frags: flush pending skbs in fqdir_pre_exit()")
> Cc: stable@xxxxxxxxxxxxxxx
> Reported-by: Kimi Security Team <bug-report@xxxxxxxxxxx>
> Tested-by: Weiming Shi <shiweiming@xxxxxxxxxxx>
> Signed-off-by: Yilin Zhang <yilinzhang@xxxxxxxxxxx>
> ---
> net/ipv4/inet_fragment.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
> --- a/net/ipv4/inet_fragment.c
> +++ b/net/ipv4/inet_fragment.c
> @@ -235,15 +235,22 @@ void fqdir_pre_exit(struct fqdir *fqdir)
> rhashtable_walk_start(&hti);
>
> while ((fq = rhashtable_walk_next(&hti))) {
> + int refs = 0;
> +
> if (IS_ERR(fq)) {
> if (PTR_ERR(fq) != -EAGAIN)
> break;
> continue;
> }
> spin_lock_bh(&fq->lock);
> - if (!(fq->flags & INET_FRAG_COMPLETE))
> + if (!(fq->flags & INET_FRAG_COMPLETE)) {
> + inet_frag_kill(fq, &refs);
> + }
OK, but remove the braces as they are not needed per kernel coding style.
if (!(fq->flags & INET_FRAG_COMPLETE))
inet_frag_kill(fq, &refs);
Reviewed-by: Eric Dumazet <edumazet@xxxxxxxxxx>
Please wait ~24 hours before sending a new version, so that other
reviewers can chime in.
Thanks.