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 0C48E514770; Wed, 30 Sep 2026 16:40:32 +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=1790786434; cv=none; b=N/V8hUlaVey2sEJ+RR7p0X0IWde1L65lwu+l73/nEfzw43WxG4M/UVWCw32X6J6DA7DwympY5wWm0iQlEIXX0M3M97ZKgGKMRevNTDAARQcECJAh9/hSDl6QVSG5imEJpOpo4Iwwjlytjs8Y/T1hW6ZAuHfL8GCrYzEnJ1t0Og8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790786434; c=relaxed/simple; bh=ShSSHxVbdgjIhvotFtOYHL2yXOw1mthBDP02sbbRp3w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Q9eaPCKDHHj8tgvQC1hz2i0I3Qsk76nuTTYgXKxb7PrdwwZgif82g2GTdEavb704hrwbDDyoaYJFA51aImgV6w/kYaId2gMtw0X10FXHxkbwGLLqjtYTBtIOs7YoYn5XzzHa2GVcFZ8T+nL8xcMQ89pLLesltiTsp6u8BkcBm50= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=WV8358CP; 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="WV8358CP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4BCA21F00893; Wed, 30 Sep 2026 16:40:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1790786432; bh=weuYhn4af0vxwJUbjBCrDxhi1SdQEpGiXI7o5+2tI/Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WV8358CP0GhiEqX5smFITxnNwuhemU/iGA6OIf2hoyfeWD4dWcKvaFVks0yMcxciz COeOVRYNVt6H6JcTel70HK5dBbNEpIIilCzEYdvwm2BJTTGSy4yV6NT2aNE/GuxpHO l8sJx8aZVqEsR0QiC22tK4DnmMg7of9RJ9UydpBk= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, =?UTF-8?q?J=C3=A9r=C3=A9my=20Jean?= , Pablo Neira Ayuso , Sasha Levin Subject: [PATCH 6.1 833/982] netfilter: flowtable: publish HW_DEAD after worker is done Date: Wed, 30 Sep 2026 17:26:09 +0200 Message-ID: <20260930152434.647753853@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260930152416.775402466@linuxfoundation.org> References: <20260930152416.775402466@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-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jérémy Jean [ Upstream commit d644b23afe1ef509c9961a6d84a093c2587edf02 ] flow_offload_work_del() sets NF_FLOW_HW_DEAD before the work handler clears NF_FLOW_HW_PENDING. Once a flow is both HW_DYING and HW_DEAD, a concurrent garbage collection pass can remove it and schedule it for RCU freeing. The offload worker holds neither an RCU read lock nor a reference to the flow. If it is preempted after publishing HW_DEAD, the RCU callback can free the flow before the worker resumes and clears HW_PENDING, resulting in a use-after-free. Move HW_DEAD publication to the common worker epilogue after the pending bit is cleared, making it the final flow access by destroy work. Order all preceding flow accesses before publishing the bit that allows garbage collection to free the object. Fixes: 2c8897953f3b ("netfilter: flowtable: Add pending bit for offload work") Assisted-by: Codex:gpt-5 Signed-off-by: Jérémy Jean Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_flow_table_offload.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c index cd8bce176ae88..1747c0af75698 100644 --- a/net/netfilter/nf_flow_table_offload.c +++ b/net/netfilter/nf_flow_table_offload.c @@ -993,7 +993,6 @@ static void flow_offload_work_del(struct flow_offload_work *offload) flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL); if (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags)) flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY); - set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags); } static void flow_offload_tuple_stats(struct flow_offload_work *offload, @@ -1057,6 +1056,12 @@ static void flow_offload_work_handler(struct work_struct *work) } clear_bit(NF_FLOW_HW_PENDING, &offload->flow->flags); + if (offload->cmd == FLOW_CLS_DESTROY) { + /* Publish after the worker's last flow access. */ + smp_mb__before_atomic(); + set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags); + } + kfree(offload); } -- 2.53.0