From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D3CC52F1FEF; Thu, 28 May 2026 20:48:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001299; cv=none; b=ez4n/UvRLVBPfaWtBM64zqXGO7UnahNbHwFN1xZ1rF6/YeliBlO/9rMR/EHWFWnLwlh8A/srIR4h7XN6rjhh93vIDQkojmB0Oqcodi0QF8FhUmc9vW6IwDeJYUTN9S8VYcwPfkf5li8Tjepxc27vK26dq2eAR+S5yCSSBKAXUcY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001299; c=relaxed/simple; bh=e/Y/0wdFREOA/BJSo96vpWGLYn72Tvqgrr/b09XztNs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JolcR8T8TCY4WCa/FVmu2j5EkpQ4aZbzUyrBX2H1rewIiBNxY13BqAEBabAXMFmHKUW6ouE+rPYQ1BzIzYWYqCHtpR+xwROPaR2Gka8GCNtVyBuNEXAU47R6WhDduEG9dRyEBMfxKYiuwmljJ25cIhawQD4D77ZcETbHiAjFWCM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=flycm7At; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="flycm7At" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 418C81F000E9; Thu, 28 May 2026 20:48:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1780001298; bh=Vi92kOQxiQbMPMZJ843wvr/5b5s8Noj0LCJBQx3EZt8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=flycm7AtGt0pkBLnyvxKVmsdQoXZrw2nJRWFk1Nn3EgX98VCohqQ16Z/c71uWCvjG 8vRxdUPDHYu11LIqEbcYku5laLKHiITfUFkKs6VCLYlxvKlhK/H75nptHM67yDfkXP WOftq6Cog9AjFungQ6UT/fyJ5C4jWWQZVnUwlHUE= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, stable@kernel.org, Yuan Tan , Yifan Wu , Juefei Pu , Xin Liu , Ruide Cao , Ren Wei , Ren Wei , Sven Eckelmann Subject: [PATCH 6.6 079/186] batman-adv: fix fragment reassembly length accounting Date: Thu, 28 May 2026 21:49:19 +0200 Message-ID: <20260528194931.069596865@linuxfoundation.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260528194928.941004471@linuxfoundation.org> References: <20260528194928.941004471@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.6-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ruide Cao commit 9cd3f16c320bfdadd4509358122368deb56a5741 upstream. batman-adv keeps a running payload length for queued fragments and uses it to validate a fragment chain before reassembly. That accounting currently allows the accumulated fragment length to be truncated during updates. As a result, malformed fragment chains can bypass the intended validation and drive reassembly with inconsistent length state, leading to a local denial of service. Fix the accounting by storing the accumulated length in a length-typed field and rejecting update overflows before the existing validation logic runs. The fix was verified against the original reproducer and against valid fragment reassembly paths. Fixes: 610bfc6bc99b ("batman-adv: Receive fragmented packets and merge") Cc: stable@kernel.org Reported-by: Yuan Tan Reported-by: Yifan Wu Reported-by: Juefei Pu Reported-by: Xin Liu Signed-off-by: Ruide Cao Tested-by: Ren Wei Signed-off-by: Ren Wei Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- net/batman-adv/fragmentation.c | 23 +++++++++++++++++------ net/batman-adv/types.h | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -81,9 +82,9 @@ void batadv_frag_purge_orig(struct batad * * Return: the maximum size of payload that can be fragmented. */ -static int batadv_frag_size_limit(void) +static size_t batadv_frag_size_limit(void) { - int limit = BATADV_FRAG_MAX_FRAG_SIZE; + size_t limit = BATADV_FRAG_MAX_FRAG_SIZE; limit -= sizeof(struct batadv_frag_packet); limit *= BATADV_FRAG_MAX_FRAGMENTS; @@ -144,7 +145,9 @@ static bool batadv_frag_insert_packet(st struct batadv_frag_packet *frag_packet; u8 bucket; u16 seqno, hdr_size = sizeof(struct batadv_frag_packet); + bool overflow = false; bool ret = false; + size_t data_len; /* Linearize packet to avoid linearizing 16 packets in a row when doing * the later merge. Non-linear merge should be added to remove this @@ -154,6 +157,7 @@ static bool batadv_frag_insert_packet(st goto err; frag_packet = (struct batadv_frag_packet *)skb->data; + data_len = skb->len - hdr_size; seqno = ntohs(frag_packet->seqno); bucket = seqno % BATADV_FRAG_BUFFER_COUNT; @@ -172,7 +176,7 @@ static bool batadv_frag_insert_packet(st spin_lock_bh(&chain->lock); if (batadv_frag_init_chain(chain, seqno)) { hlist_add_head(&frag_entry_new->list, &chain->fragment_list); - chain->size = skb->len - hdr_size; + chain->size = data_len; chain->timestamp = jiffies; chain->total_size = ntohs(frag_packet->total_size); ret = true; @@ -189,7 +193,11 @@ static bool batadv_frag_insert_packet(st if (frag_entry_curr->no < frag_entry_new->no) { hlist_add_before(&frag_entry_new->list, &frag_entry_curr->list); - chain->size += skb->len - hdr_size; + + if (check_add_overflow(chain->size, data_len, + &chain->size)) + overflow = true; + chain->timestamp = jiffies; ret = true; goto out; @@ -202,13 +210,16 @@ static bool batadv_frag_insert_packet(st /* Reached the end of the list, so insert after 'frag_entry_last'. */ if (likely(frag_entry_last)) { hlist_add_behind(&frag_entry_new->list, &frag_entry_last->list); - chain->size += skb->len - hdr_size; + + if (check_add_overflow(chain->size, data_len, &chain->size)) + overflow = true; + chain->timestamp = jiffies; ret = true; } out: - if (chain->size > batadv_frag_size_limit() || + if (overflow || chain->size > batadv_frag_size_limit() || chain->total_size != ntohs(frag_packet->total_size) || chain->total_size > batadv_frag_size_limit()) { /* Clear chain if total size of either the list or the packet --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -295,7 +295,7 @@ struct batadv_frag_table_entry { u16 seqno; /** @size: accumulated size of packets in list */ - u16 size; + size_t size; /** @total_size: expected size of the assembled packet */ u16 total_size;