From: Lee Jones <lee@kernel.org>
To: Tung Quang Nguyen <tung.quang.nguyen@est.tech>
Cc: Jon Maloy <jmaloy@redhat.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"tipc-discussion@lists.sourceforge.net"
<tipc-discussion@lists.sourceforge.net>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 1/1] tipc: fix double-free in tipc_buf_append()
Date: Tue, 21 Apr 2026 11:35:43 +0100 [thread overview]
Message-ID: <20260421103543.GH3202366@google.com> (raw)
In-Reply-To: <20260420151040.GF3202366@google.com>
On Mon, 20 Apr 2026, Lee Jones wrote:
> On Mon, 20 Apr 2026, Tung Quang Nguyen wrote:
>
> > >> Subject: [PATCH 1/1] tipc: fix double-free in tipc_buf_append()
> > >> >
> > >> >The tipc_msg_validate() function can potentially reallocate the skb
> > >> >it is validating, freeing the old one. In tipc_buf_append(), it was
> > >> >being called with a pointer to a local variable which was a copy of the
> > >caller's skb pointer.
> > >> >
> > >> >If the skb was reallocated and validation subsequently failed, the
> > >> >error handling path would free the original skb pointer, which had
> > >> >already been freed, leading to double-free.
> > >> >
> > >> >Fix this by passing the caller's skb pointer-pointer directly to
> > >> >tipc_msg_validate(), ensuring any modification is reflected correctly.
> > >> >The local skb pointer is then updated from the (possibly modified)
> > >> >caller's pointer.
> > >> >
> > >> >Fixes: d618d09a68e4 ("tipc: enforce valid ratio between skb truesize
> > >> >and
> > >> >contents")
> > >> >Assisted-by: Gemini:gemini-3.1-pro-preview
> > >> >Signed-off-by: Lee Jones <lee@kernel.org>
> > >> >---
> > >> > net/tipc/msg.c | 3 ++-
> > >> > 1 file changed, 2 insertions(+), 1 deletion(-)
> > >> >
> > >> >diff --git a/net/tipc/msg.c b/net/tipc/msg.c index
> > >> >76284fc538eb..9f4f612ee027
> > >> >100644
> > >> >--- a/net/tipc/msg.c
> > >> >+++ b/net/tipc/msg.c
> > >> >@@ -177,8 +177,9 @@ int tipc_buf_append(struct sk_buff **headbuf,
> > >> >struct sk_buff **buf)
> > >> >
> > >> > if (fragid == LAST_FRAGMENT) {
> > >> > TIPC_SKB_CB(head)->validated = 0;
> > >> >- if (unlikely(!tipc_msg_validate(&head)))
> > >> >+ if (unlikely(!tipc_msg_validate(headbuf)))
> > >> > goto err;
> > >> >+ head = *headbuf;
> > >> This is a known issue and was reported via
> > >> https://patchwork.kernel.org/project/netdevbpf/patch/20260330205313.24
> > >> 33372-1-nicholas@carlini.com/ The author did not respond to my
> > >> comment.
> > >> Can you improve the fix by applying my patch?
> > >
> > >I'd be happy to make any required changes.
> > >
> > >However, is this approach superior to simply passing a reference?
> > >
> > >v1 appears to be simpler, easier to read and avoids the explanation.
> > >
> > As I explained, your fix adds extra overhead to normal path while the error path is corner case and it rarely happens.
> > Whatever approach is applied, we need to add explanation to understand more easily the logic and hidden trick in tipc_msg_validate().
>
> Very well. I have made the recommended changes.
>
> The patch is currently in my build-test environment.
>
> I will post v2, when everything has been satisfied.
Okay, I genuinely tried to apply your patch. It builds just fine, but
Gemini (the AI I use to pre-review patches before submission) has some
doubts that this is the correct approach:
> @@ -177,8 +177,20 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
>
> if (fragid == LAST_FRAGMENT) {
> TIPC_SKB_CB(head)->validated = 0;
> - if (unlikely(!tipc_msg_validate(&head)))
> +
> + /* If the reassembled skb has been freed in
> + * tipc_msg_validate() because of an invalid truesize,
> + * then head will point to a newly allocated reassembled
> + * skb, while *headbuf points to freed reassembled skb.
> + * In such cases, correct *headbuf for freeing the newly
> + * allocated reassembled skb later.
> + *
> + * Note: It's done this way instead of passing &head // I added this part to give
> + * to avoid slowing down the happy path since this failure // the reviewer some additoinal
> + * is a rare event. // context
> + */
> + if (unlikely(!tipc_msg_validate(headbuf))) {
> + if (head != *headbuf)
> + *headbuf = head;
> goto err;
> + }
> +
"It looks like this logic might re-introduce the double-free bug.
The call to `tipc_msg_validate(headbuf)` is correct, as it passes the
pointer-to-pointer and allows the callee to update `*headbuf` if the skb
is reallocated.
However, the subsequent check seems to undo this. If a reallocation
happens, `head` will hold the pointer to the old, freed skb, while
`*headbuf` will hold the new one. The condition `head != *headbuf` will
be true, and the assignment `*headbuf = head` will restore the stale
pointer, leading to a double-free on the `err` path.
The preceding comment also appears to have the pointer roles reversed.
Would it be simpler and more correct to remove the `if (head != *headbuf)`
check and the large comment block? The change from `&head` to `headbuf`
in the function call seems to be the only change required to fix the bug.
Also, please update the commit message to reflect the corrected logic."
I suggest that we go with the original patch. Although I find it admirable
that you are thinking about and attempting to protect the more common
happy-path, I think the resultant single additional variable assignment
is negligible and that the simplicity of the previous fix has greater
benefits in terms of code readability and maintainability.
If you like, I can add a small comment, but I doubt even that is necessary.
--
Lee Jones [李琼斯]
next prev parent reply other threads:[~2026-04-21 10:35 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-20 13:05 [PATCH 1/1] tipc: fix double-free in tipc_buf_append() Lee Jones
2026-04-20 13:46 ` Tung Quang Nguyen
2026-04-20 14:33 ` Lee Jones
2026-04-20 14:49 ` Tung Quang Nguyen
2026-04-20 15:10 ` Lee Jones
2026-04-21 10:35 ` Lee Jones [this message]
2026-04-21 12:10 ` Tung Quang Nguyen
2026-04-21 12:28 ` Lee Jones
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=20260421103543.GH3202366@google.com \
--to=lee@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jmaloy@redhat.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=tipc-discussion@lists.sourceforge.net \
--cc=tung.quang.nguyen@est.tech \
/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.