From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f173.google.com (mail-qt1-f173.google.com [209.85.160.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A63963EC800 for ; Fri, 31 Jul 2026 14:08:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.173 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785506895; cv=none; b=nqMu6B2rVxjya/1tPdRLOUkYCMjK0hNNY50+WRa5KjaZjIwg117iRO2+wlh+1/GxOV6jkxifGrcQJUKEu7Mre/DDNEIvwpF5mLvUB/yCX/omtoDh30H445x5yhT/Oc9Bj0zhkerVavydsdrIfLf/WpTNJ39gLTFYpXFOhszpALw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785506895; c=relaxed/simple; bh=lWYS/jQQIXC0y44IHuPBs/Bn1BGmlDCz4C7AQHJjUxw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=kxyry4TqjP0M9ovcLX2zIFNBOCKLrhpIFPZ6YKepBKnOA8tWCxQym+eTW663SSNyMXZWBXkA32jbAGk6cIJzR7zDaIVEWXcuSbcSARYs1X6K/uJmhtlLPJp1y4apLKhRQzQrgWo4SICHneN93QRFy1mOwWOF1gq4blnHfoVqJ9Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=trailofbits.com; spf=pass smtp.mailfrom=trailofbits.com; dkim=pass (2048-bit key) header.d=trailofbits.com header.i=@trailofbits.com header.b=cnikELOM; arc=none smtp.client-ip=209.85.160.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=trailofbits.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=trailofbits.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=trailofbits.com header.i=@trailofbits.com header.b="cnikELOM" Received: by mail-qt1-f173.google.com with SMTP id d75a77b69052e-51c16ac21acso6019031cf.0 for ; Fri, 31 Jul 2026 07:08:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=trailofbits.com; s=google; t=1785506892; x=1786111692; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=H1m5R8ifW3apJu3sUYJF9SxlauvcUbf0bTaC1a+0HJY=; b=cnikELOMVZ6CYvzmcILg9PK74aKJ0kKV6sqj0IdsEMOUZEpdES8YwbzjOlHH6QOyLf T+uaLvOSZoGp7FSjuzV3pQLfp2EKKDZCdcW+ohyyZeEvLQAT8W7oehQN/n/glDFePoqC Ze4tbdaK8nXM/jDQavdRIpSE/cRzGXKaopwENnYjup4chbRsk8QWcJK0RPAGxnr6F/ta 4DMnVXz4gbkG1YTHCwTCaF+w+AMKlj562OSr7AX9GG1wCozqUyRWiGeGlN3A/wFQfd4T 9mLxIq1mlPqwDRvz6910m/O8XkjzRvIgzzjLNkEqazKsVOYFCzxxv0sg6umtb8rqYXK0 aVPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785506892; x=1786111692; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=H1m5R8ifW3apJu3sUYJF9SxlauvcUbf0bTaC1a+0HJY=; b=SBZuhhcQsG3ADj1kUokHx2w0RKNTW1ag2+mRxHXVQ/e6c5ISypWy/qSMXZyhlw2pgo mnSvOB28xJkcm00dH8z80CvwVMOeFyeZefXjXEFqubqLug+gCn1vhigEnfCWmm2eBqAX oO9kKz3P55IJvNsoboOg/dAJV9RIreV7S6C+ap+uMsqIsCt0V8LcBvIYmf4QTo9Zy2k1 vREuqruIn8Il5ZIRNHsZ7Zdwv5BRcP0BYXIITatlvYXT7brrVDLemEpJ/lXnGrFoEeG4 j67r2Jklre4zMvRVZKEqp57+RMuF3pQzFXp6+sl2uIGuVp4j8jTphbf1cutgD40dE8jz Lm8Q== X-Forwarded-Encrypted: i=1; AHgh+Rp139aUbV7ci4/uY9qozQ0KK+Lv+8fcFI+K7dAT7JDQJz01H0v4bJQCPA6lWjUc8TZKQ4Cmmh7BLnHnEY8=@vger.kernel.org X-Gm-Message-State: AOJu0YxsiS09S7rzgMW+pmOu6c+ESk5wYQgWkbgrJGlGHyfgLUWyYbOC Q1dMihGARV+zc5y8izJ2B5li4+SBv2Z9VZR3rqyMTX6kGbAlgnMGMcXQuyS/y/Olb4k= X-Gm-Gg: AR+sD12Ofwa1V1Sb1NZ19JOkwz1qUxBnrJXLr3moNecz+FBlRPhQ/3XMjppPnagcu3m 2JGlkhgRhNBAxr8toQLv42UX/U5n9jM9Uc0smVe5JtAg4o0xSiO7fjsOwgry6DljtnjUOx9qcKW YNQBkUqL6ZpGaJ3v3Qf6hzZdXt2HHC1TRwwGkunxm8mP29KhTWTfsHbm0G3thV9V8XkOSVy8hbP zS3PF6hqziUa2Le8nn5Qw6ynzAHlchygPBq8Bg3A4EY7F2IFXrccSBDtot+MZQIIk6L+KjWpCqe 8iFYfZugl6x76+kaRtaGUJcmAFdV2bOUTOsyhv+MQGr5yo2B55hqeHGxdk3k57yGNHdknx8J4EE N1MkeIiXTR9lXeFNcrH/55VVeNKBfnuNCB1cvTY4JghPRCK60xrGcaXbtM7CbdyX6/Ly1d6xcem nIkdVb3LqvMNrOGqhTM6hO21msBapUyz/sh3YmjRw+gVCWy3QAuFQJ0IhxzeJsZjYQajmoYjpey ZsK X-Received: by 2002:a05:622a:400d:b0:528:3d62:16c8 with SMTP id d75a77b69052e-52b56794317mr4487941cf.31.1785506892382; Fri, 31 Jul 2026 07:08:12 -0700 (PDT) Received: from localhost ([146.190.222.192]) by smtp.gmail.com with UTF8SMTPSA id d75a77b69052e-52b4e81edadsm8626151cf.8.2026.07.31.07.08.11 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 31 Jul 2026 07:08:12 -0700 (PDT) From: David Lee To: pablo@netfilter.org, fw@strlen.de, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com Cc: David Lee , Kyle Zeng , Dominik 'Disconnect3d' Czarnota , phil@nwl.cc, horms@kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] netfilter: nf_conntrack: prevent helper extension relocation Date: Fri, 31 Jul 2026 14:08:10 +0000 Message-ID: <20260731140811.566714-1-david.lee@trailofbits.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit struct nf_conn_help contains the head of the per-master expectation list. hlist_add_head_rcu() makes the first expectation node point back to that head, but nf_ct_ext_add() can later move the extension buffer with krealloc(). This leaves the node backpointer aimed at freed memory, so unlinking the expectation writes through a stale pointer. Reserve the full u8-addressable extension space when adding the helper extension and reuse the existing buffer once the helper is present. This keeps the expectation list head stable while allowing later extensions to be added. Fixes: 857b46027d6f ("netfilter: nft_ct: add ct expectations support") Bug found and triaged by OpenAI Security Research and validated by Trail of Bits. Assisted-by: Codex:gpt-5.6-sol gpt-5.5-cyber Signed-off-by: Kyle Zeng --- Trail of Bits has a reproducer for this bug that triggers a KASAN use-after-free and can share if needed. net/netfilter/nf_conntrack_extend.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 0da105e1d..1421944a3 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -112,9 +112,21 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) newlen = newoff + nf_ct_ext_type_len[id]; alloc = max(newlen, NF_CT_EXT_PREALLOC); - new = krealloc(ct->ext, alloc, gfp); - if (!new) - return NULL; + /* + * Once an expectation is linked, its list node points back to the + * hlist head in the helper extension. Reserve all available extension + * space for the helper and do not move it afterward. + */ + if (ct->ext && + __nf_ct_ext_exist(ct->ext, NF_CT_EXT_HELPER)) { + new = ct->ext; + } else { + if (id == NF_CT_EXT_HELPER) + alloc = U8_MAX; + new = krealloc(ct->ext, alloc, gfp); + if (!new) + return NULL; + } if (!ct->ext) memset(new->offset, 0, sizeof(new->offset)); -- 2.53.0