From nobody Sat Jul 25 02:35:48 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (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 465734189DD; Mon, 20 Jul 2026 13:41:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554884; cv=none; b=sc6ZA2AjH58SzHIq/cSkQmrsw/fSIpWfV83GV13UJYwlztgtVRmqWkeQMG1RTSiqdByPAIWxlFHJxdVjEbJC7EDYysFfkTL9tFpCShUcEts8mEqQt/o9OBpuWbjXF/JttoYdsH3gcyx6o0MxdBB8vhuTfeN4MO6QXEYzWa7HiIA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554884; c=relaxed/simple; bh=6mwXexKeeGg/cdWz6Fb8ep3ueP8EDnUAMj4EUk8irSw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qD05S3APsxiYgStahdlO+vCH2yqmWZkyVh5hAQI54pXl41xDN/v/6SE4JdPFFUfhBioOf/a7LTVNLX2wHezdnJ7D2KqXL4t2wo8oY5gpyPDGTqYt2fvDDb8PbVPyU/nO7Ntjx2oT8aQ/wxOD2FGdH2uERItAfG8DAWJwuULHQDQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4h3hVF4pzzzKHMRK; Mon, 20 Jul 2026 21:40:37 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 269E940539; Mon, 20 Jul 2026 21:41:18 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgDn9XF8JV5qIAesBw--.40451S3; Mon, 20 Jul 2026 21:41:18 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Emil Tsalapatis , Pu Lehui , Pu Lehui Subject: [PATCH bpf v4 1/4] bpf: Fix potential UAF in bpf_netns_link_update_prog Date: Mon, 20 Jul 2026 13:45:44 +0000 Message-Id: <20260720134547.1289964-2-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260720134547.1289964-1-pulehui@huaweicloud.com> References: <20260720134547.1289964-1-pulehui@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgDn9XF8JV5qIAesBw--.40451S3 X-Coremail-Antispam: 1UD129KBjvJXoW7tr1xJw4kCF1Utr17uF48WFg_yoW8Cr1fpF y3Cr1DWw10krsF9F18X3WkuryrXFy0gr1UCr1DZ3W0qFyIqr1Fg34UurZ29rsY9FWvgryS qa4qgr4Yqw1jva7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUm014x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r4j6ryUM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Jr0_JF4l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1l84 ACjcxK6I8E87Iv67AKxVWxJr0_GcWl84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2AI xVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20x vE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xv r2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2IY04 v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j 6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7 AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE 2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcV C2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBIdaVFxhVj vjDU0xZFpf9x0JU4OJ5UUUUU= X-CM-SenderInfo: psxovxtxl6x35dzhxuhorxvhhfrp/ Content-Type: text/plain; charset="utf-8" From: Pu Lehui In bpf_netns_link_update_prog, the checks for old_prog and prog type are currently performed locklessly before acquiring netns_bpf_mutex. This creates a race condition that can lead to a UAF issue. If two threads concurrently execute BPF_LINK_UPDATE on the same netns link, the following execution path can trigger a UAF: CPU0 CPU1 bpf_netns_link_update_prog if (old_prog && old_prog !=3D link->prog) return -EPERM; bpf_netns_link_update_prog if (old_prog && old_prog != =3D link->prog) ... old_prog =3D xchg(&link->pr= og, new_prog); bpf_prog_put(old_prog); if (new_prog->type !=3D link->prog->type) <-- trigger UAF Fix this by moving the old_prog and prog->type checks inside the netns_bpf_mutex critical section. Fixes: 7f045a49fee0 ("bpf: Add link-based BPF program attachment to network= namespace") Reported-by: Sashiko Signed-off-by: Pu Lehui Reviewed-by: Amery Hung --- kernel/bpf/net_namespace.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/kernel/bpf/net_namespace.c b/kernel/bpf/net_namespace.c index 25f30f9edaef..9fc62db1441c 100644 --- a/kernel/bpf/net_namespace.c +++ b/kernel/bpf/net_namespace.c @@ -171,13 +171,17 @@ static int bpf_netns_link_update_prog(struct bpf_link= *link, struct net *net; int idx, ret; =20 - if (old_prog && old_prog !=3D link->prog) - return -EPERM; - if (new_prog->type !=3D link->prog->type) - return -EINVAL; - mutex_lock(&netns_bpf_mutex); =20 + if (old_prog && old_prog !=3D link->prog) { + ret =3D -EPERM; + goto out_unlock; + } + if (new_prog->type !=3D link->prog->type) { + ret =3D -EINVAL; + goto out_unlock; + } + net =3D net_link->net; if (!net || !check_net(net)) { /* Link auto-detached or netns dying */ --=20 2.34.1 From nobody Sat Jul 25 02:35:48 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (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 38FF3426D2E; Mon, 20 Jul 2026 13:41:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554889; cv=none; b=py+jD4AE3oWJLAqQXh+ExGxDO7hPCIG4DeACUP8XAvCvkCHA3s0E3CiYky9PaVSkWdeWWV8FwjVPNf7AmD8t9p/I7e77R81qQyGvoXvv5PqVg13l5ZvTEQ6LDsJRsSLX4cUcowpeajWSYlx5cXIAoC1Vjlls16bRMIpbhD3B0dM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554889; c=relaxed/simple; bh=hB60V6OwzV5OdjIuZ3aCVbVNuw5mBlyw7PI3r840VR0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cCwBO25Xq7dkf5+Kt5FxbEfBCL49cbG8gY2rpkgbSlgyOIJQPzfz9GQD3hDV51CPbYVRz2lkCZHEl0afEpWO256P02p2kwE2M5twqKfJ8rtncgZbrMiI2M9zLmyE3LAvhDn2PKL9kt2e67I17LsXPViaYeX+ZH7ZhcFJPAyISnM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4h3hVX3f01zYQtyM; Mon, 20 Jul 2026 21:40:52 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 2E566407D5; Mon, 20 Jul 2026 21:41:18 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgDn9XF8JV5qIAesBw--.40451S4; Mon, 20 Jul 2026 21:41:18 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Emil Tsalapatis , Pu Lehui , Pu Lehui Subject: [PATCH bpf v4 2/4] bpf: Fix UAF due to missing link type check in mprog Date: Mon, 20 Jul 2026 13:45:45 +0000 Message-Id: <20260720134547.1289964-3-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260720134547.1289964-1-pulehui@huaweicloud.com> References: <20260720134547.1289964-1-pulehui@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgDn9XF8JV5qIAesBw--.40451S4 X-Coremail-Antispam: 1UD129KBjvJXoWxZr47Gr4kXFWfCw1UGry8Zrb_yoW5ZF1xpF s3Jryvyr1Yv3y7XF4jvF1fArWY9F48Wr1jka4rWw4vvFn09a1vqF13Wr4Sqw15KFZ8Jwsa vw1qqryDJ34DXrDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmY14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jryl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Jr0_JF4l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UM2 8EF7xvwVC2z280aVAFwI0_Cr1j6rxdM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0x vEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIev Ja73UjIFyTuYvjfUOdgAUUUUU X-CM-SenderInfo: psxovxtxl6x35dzhxuhorxvhhfrp/ Content-Type: text/plain; charset="utf-8" From: Pu Lehui In bpf_mprog_link, the code does not check the link->type first before dereferencing link->prog->type. This missing validation allows a user to pass an abnormal non-netkit or non-tcx link via relative_fd. If do BPF_LINK_UPDATE on the abnormal link, it can trigger a UAF issue. CPU0 CPU1 netkit_link_prog_attach bpf_mprog_attach bpf_mprog_tuple_relative bpf_mprog_link link =3D bpf_link_get_from_fd(id_or_fd); BPF_LINK_UPDATE ... old_prog =3D xchg(&link->link.pro= g, new_prog); bpf_prog_put(old_prog); if (type && link->prog->type !=3D type) <-- trigger UAF Fix this by strictly validate link->type in bpf_mprog_link against the expected link type. bpf_mprog_tuple_relative is also adjusted to accept and pass down the expected link type. Fixes: 053c8e1f235d ("bpf: Add generic attach/detach/query API for multi-pr= ogs") Reported-by: Sashiko Signed-off-by: Pu Lehui Reviewed-by: Amery Hung --- kernel/bpf/mprog.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/kernel/bpf/mprog.c b/kernel/bpf/mprog.c index 1394168062e8..367f8f10da0a 100644 --- a/kernel/bpf/mprog.c +++ b/kernel/bpf/mprog.c @@ -6,7 +6,7 @@ =20 static int bpf_mprog_link(struct bpf_tuple *tuple, u32 id_or_fd, u32 flags, - enum bpf_prog_type type) + enum bpf_link_type type) { struct bpf_link *link =3D ERR_PTR(-EINVAL); bool id =3D flags & BPF_F_ID; @@ -17,7 +17,7 @@ static int bpf_mprog_link(struct bpf_tuple *tuple, link =3D bpf_link_get_from_fd(id_or_fd); if (IS_ERR(link)) return PTR_ERR(link); - if (type && link->prog->type !=3D type) { + if (type && link->type !=3D type) { bpf_link_put(link); return -EINVAL; } @@ -52,21 +52,22 @@ static int bpf_mprog_prog(struct bpf_tuple *tuple, =20 static int bpf_mprog_tuple_relative(struct bpf_tuple *tuple, u32 id_or_fd, u32 flags, - enum bpf_prog_type type) + enum bpf_link_type ltype, + enum bpf_prog_type ptype) { bool link =3D flags & BPF_F_LINK; bool id =3D flags & BPF_F_ID; =20 memset(tuple, 0, sizeof(*tuple)); if (link) - return bpf_mprog_link(tuple, id_or_fd, flags, type); + return bpf_mprog_link(tuple, id_or_fd, flags, ltype); /* If no relevant flag is set and no id_or_fd was passed, then * tuple link/prog is just NULLed. This is the case when before/ * after selects first/last position without passing fd. */ if (!id && !id_or_fd) return 0; - return bpf_mprog_prog(tuple, id_or_fd, flags, type); + return bpf_mprog_prog(tuple, id_or_fd, flags, ptype); } =20 static void bpf_mprog_tuple_put(struct bpf_tuple *tuple) @@ -243,6 +244,8 @@ int bpf_mprog_attach(struct bpf_mprog_entry *entry, return -EEXIST; ret =3D bpf_mprog_tuple_relative(&rtuple, id_or_fd, flags & ~BPF_F_REPLACE, + link ? link->type : + BPF_LINK_TYPE_UNSPEC, prog_new->type); if (ret) return ret; @@ -343,6 +346,8 @@ int bpf_mprog_detach(struct bpf_mprog_entry *entry, if (!bpf_mprog_total(entry)) return -ENOENT; ret =3D bpf_mprog_tuple_relative(&rtuple, id_or_fd, flags, + link ? link->type : + BPF_LINK_TYPE_UNSPEC, prog ? prog->type : BPF_PROG_TYPE_UNSPEC); if (ret) --=20 2.34.1 From nobody Sat Jul 25 02:35:48 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (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 38EAC3DB647; Mon, 20 Jul 2026 13:41:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554893; cv=none; b=SNZEUacZ4ZTeHHTKXl/rRCgwFsTp4fYpqPT+gBXTTAtbczSLxFjIzJV702WOxlr1hJyLBHMKaSdOcfCFd3p0uKLNjwxzgoItJ8CWhhd72GTgw4toH8YFl5VhwlZp8VTozqD6cBlzUxRllRTdwph75nORiHqbJVzTn6oev4CJZCU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554893; c=relaxed/simple; bh=/U653KpXYtfMy0gy6f3P5N8exn+7Iab6m3Bcx+8MD+Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Mb2tYf2CpBtZdUVLeEK48OTK0J9jxrb1Dt3wSQvxnjut1Tmb33kmkhULpzT7HtD5rPVhlCl6IAk2kQkLB57Sap8OApNcV3UUTh8I/84xa8HQxTpWqgrwcowHOtqOl0p7kARrp1yySBNcCCgs6i4+UZl3lXL2N71tHgSlksB+EjQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4h3hVX4NwKzYQv0p; Mon, 20 Jul 2026 21:40:52 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 482C640947; Mon, 20 Jul 2026 21:41:18 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgDn9XF8JV5qIAesBw--.40451S5; Mon, 20 Jul 2026 21:41:18 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Emil Tsalapatis , Pu Lehui , Pu Lehui Subject: [PATCH bpf v4 3/4] bpf: Fix potential UAF when reading bpf link info Date: Mon, 20 Jul 2026 13:45:46 +0000 Message-Id: <20260720134547.1289964-4-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260720134547.1289964-1-pulehui@huaweicloud.com> References: <20260720134547.1289964-1-pulehui@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgDn9XF8JV5qIAesBw--.40451S5 X-Coremail-Antispam: 1UD129KBjvJXoWxJFyfGryUurWUGF4UJw1fZwb_yoW5Wr1fpF W3G3Wqka15ur4293W7ArW5urySgFW8WFyUKF9rW34FyF1aqrZYg34UCFWfZr9I9F97GrWf X3yjva43Gr17ZFUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmF14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JrWl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UM2 8EF7xvwVC2z280aVAFwI0_Cr1j6rxdM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42 IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2 KfnxnUUI43ZEXa7VUbpwZ7UUUUU== X-CM-SenderInfo: psxovxtxl6x35dzhxuhorxvhhfrp/ Content-Type: text/plain; charset="utf-8" From: Pu Lehui In bpf_link_show_fdinfo and bpf_link_get_info_by_fd, link->prog is accessed without holding any locks. If the prog is concurrently replaced via bpf_link_update, the old prog can be freed, leading to a potential UAF issue. Fix this by holding both normal RCU and tasks trace RCU read locks before dereferencing the prog, as BPF_LINK_TYPE_ITER support both non-sleepable and sleepable progs. Fixes: 0c991ebc8c69 ("bpf: Implement bpf_prog replacement for an active bpf= _cgroup_link") Reported-by: Sashiko Signed-off-by: Pu Lehui --- kernel/bpf/syscall.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 6db306d23b47..2458c68146b9 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -3471,9 +3471,10 @@ static const char *bpf_link_type_strs[] =3D { static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp) { const struct bpf_link *link =3D filp->private_data; - const struct bpf_prog *prog =3D link->prog; + const struct bpf_prog *prog; enum bpf_link_type type =3D link->type; char prog_tag[sizeof(prog->tag) * 2 + 1] =3D { }; + u32 prog_id; =20 if (type < ARRAY_SIZE(bpf_link_type_strs) && bpf_link_type_strs[type]) { if (link->type =3D=3D BPF_LINK_TYPE_KPROBE_MULTI) @@ -3490,13 +3491,23 @@ static void bpf_link_show_fdinfo(struct seq_file *m= , struct file *filp) } seq_printf(m, "link_id:\t%u\n", link->id); =20 + /* prog can be sleepable */ + rcu_read_lock_trace(); + rcu_read_lock(); + prog =3D READ_ONCE(link->prog); if (prog) { bin2hex(prog_tag, prog->tag, sizeof(prog->tag)); + prog_id =3D prog->aux->id; + } + rcu_read_unlock(); + rcu_read_unlock_trace(); + + if (prog) { seq_printf(m, "prog_tag:\t%s\n" "prog_id:\t%u\n", prog_tag, - prog->aux->id); + prog_id); } if (link->ops->show_fdinfo) link->ops->show_fdinfo(link, m); @@ -5535,6 +5546,7 @@ static int bpf_link_get_info_by_fd(struct file *file, { struct bpf_link_info __user *uinfo =3D u64_to_user_ptr(attr->info.info); struct bpf_link_info info; + const struct bpf_prog *prog; u32 info_len =3D attr->info.info_len; int err; =20 @@ -5549,8 +5561,15 @@ static int bpf_link_get_info_by_fd(struct file *file, =20 info.type =3D link->type; info.id =3D link->id; - if (link->prog) - info.prog_id =3D link->prog->aux->id; + + /* prog can be sleepable */ + rcu_read_lock_trace(); + rcu_read_lock(); + prog =3D READ_ONCE(link->prog); + if (prog) + info.prog_id =3D prog->aux->id; + rcu_read_unlock(); + rcu_read_unlock_trace(); =20 if (link->ops->fill_link_info) { err =3D link->ops->fill_link_info(link, &info); --=20 2.34.1 From nobody Sat Jul 25 02:35:48 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (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 D30B73DB647; Mon, 20 Jul 2026 13:41:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554884; cv=none; b=VldFLm0ObiCdAqBnEdVBuuwogn4r0CyBzW8MAy/abs8rSdaLTZe15XikdBJwxhczn/oZkO2nXS9Ky9SnCtTeDuYozSMLLNCv2/wX+YBW3l5ggfgIu1+QHGs1NDX+qf0f3cL4p9tfeEyj7pmt7z4xuC65rpcKPBWoBUmngo77qYE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784554884; c=relaxed/simple; bh=OHr6dNveuGp2ZYUpW86f177ahnXeL5Q4y5EL8JRLwdk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hD4eVlflHz7EhBsTKtQZLNI9bNxrXCuYGDVWMgTZku+kJEUzgcMwBYD8M8IAWDDhrnwX8ReMdQ0PhbfKlnnUU6k8dfj6WDwGJDUXWeRltC+cbn4/C6WJgqAjiedilo13XF21iUiDgx9+TGB5jg4UeK9Tcmk6VeO/7BQWHdzifuM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4h3hVF5f9YzKHMZy; Mon, 20 Jul 2026 21:40:37 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 4AD214056D; Mon, 20 Jul 2026 21:41:18 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgDn9XF8JV5qIAesBw--.40451S6; Mon, 20 Jul 2026 21:41:18 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Emil Tsalapatis , Pu Lehui , Pu Lehui Subject: [PATCH bpf v4 4/4] bpf, cgroup: Fix storage null-ptr-deref after replacing prog Date: Mon, 20 Jul 2026 13:45:47 +0000 Message-Id: <20260720134547.1289964-5-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260720134547.1289964-1-pulehui@huaweicloud.com> References: <20260720134547.1289964-1-pulehui@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgDn9XF8JV5qIAesBw--.40451S6 X-Coremail-Antispam: 1UD129KBjvJXoWxCF13ArW3Zw17Ar4DXFWrXwb_yoWrKF1kpF 1kAwn8tw1UX39avF1kJ39FvF1rAa10qr1UKrZ8tw1Fkay7tayFg347CryYva43uF1DWr1f tw1YvF4jk3WjvFUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUma14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr 1UM28EF7xvwVC2z280aVAFwI0_Cr1j6rxdM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsG vfC2KfnxnUUI43ZEXa7VUbPC7UUUUUU== X-CM-SenderInfo: psxovxtxl6x35dzhxuhorxvhhfrp/ Content-Type: text/plain; charset="utf-8" From: Pu Lehui Syzkaller reported a storage null-ptr-deref issue after replacing prog. This occurs in the following scenario: 1. prog A, an empty prog, is attached to a cgrp. 2. prog B uses BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE and calls the bpf_get_local_storage helper. 3. link_update is called to replace prog A with prog B. The reason is that __cgroup_bpf_replace fails to alloc and assign the required cgrp storage for the incoming replacement prog. Consequently, the new prog inherits an uninit storage, leading to null-ptr-deref panic when kick the new prog. Fix this by properly allocating the storage and comparing the old and new storage pointers. If the storage changed, fallback to update_effective_progs which performs a RCU-safe update of the entire array. If the storage remains unchanged, we can safely retain the fast-path in-place update. Additionally, handle the error path in __cgroup_bpf_attach strictly. Although it is rare for update_effective_progs to fail in this context, proper rollbacks for storage and flags are added for code rigor. Fixes: 0c991ebc8c69 ("bpf: Implement bpf_prog replacement for an active bpf= _cgroup_link") Signed-off-by: Pu Lehui Reviewed-by: Amery Hung --- kernel/bpf/cgroup.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 4355ccb78a9c..56d538f05520 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -813,10 +813,12 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *old_prog =3D NULL; struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] =3D {}; struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] =3D {= }; + struct bpf_cgroup_storage *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] =3D {= }; struct bpf_prog *new_prog =3D prog ? : link->link.prog; enum cgroup_bpf_attach_type atype; struct bpf_prog_list *pl; struct hlist_head *progs; + u8 old_flags; int err; =20 if (((flags & BPF_F_ALLOW_OVERRIDE) && (flags & BPF_F_ALLOW_MULTI)) || @@ -883,7 +885,10 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp, pl->prog =3D prog; pl->link =3D link; pl->flags =3D flags; + if (old_prog) + bpf_cgroup_storages_assign(old_storage, pl->storage); bpf_cgroup_storages_assign(pl->storage, storage); + old_flags =3D cgrp->bpf.flags[atype]; cgrp->bpf.flags[atype] =3D saved_flags; =20 if (type =3D=3D BPF_LSM_CGROUP) { @@ -915,12 +920,14 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp, if (old_prog) { pl->prog =3D old_prog; pl->link =3D NULL; + bpf_cgroup_storages_assign(pl->storage, old_storage); } bpf_cgroup_storages_free(new_storage); if (!old_prog) { hlist_del(&pl->node); kfree(pl); } + cgrp->bpf.flags[atype] =3D old_flags; return err; } =20 @@ -1032,11 +1039,17 @@ static int __cgroup_bpf_replace(struct cgroup *cgrp, struct bpf_cgroup_link *link, struct bpf_prog *new_prog) { + struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] =3D {= }; + struct bpf_cgroup_storage *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] =3D {= }; + struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] =3D {}; + enum bpf_cgroup_storage_type stype; enum cgroup_bpf_attach_type atype; + bool storage_changed =3D false; struct bpf_prog *old_prog; struct bpf_prog_list *pl; struct hlist_head *progs; bool found =3D false; + int err; =20 atype =3D bpf_cgroup_atype_find(link->link.attach_type, new_prog->aux->at= tach_btf_id); if (atype < 0) @@ -1056,10 +1069,39 @@ static int __cgroup_bpf_replace(struct cgroup *cgrp, if (!found) return -ENOENT; =20 + if (bpf_cgroup_storages_alloc(storage, new_storage, link->link.attach_typ= e, + new_prog, cgrp)) + return -ENOMEM; + + for_each_cgroup_storage_type(stype) { + if (storage[stype] !=3D pl->storage[stype]) { + storage_changed =3D true; + break; + } + } + cgrp->bpf.revisions[atype] +=3D 1; old_prog =3D xchg(&link->link.prog, new_prog); - replace_effective_prog(cgrp, atype, pl); + + if (!storage_changed) { + replace_effective_prog(cgrp, atype, pl); + bpf_prog_put(old_prog); + return 0; + } + + bpf_cgroup_storages_assign(old_storage, pl->storage); + bpf_cgroup_storages_assign(pl->storage, storage); + err =3D update_effective_progs(cgrp, atype); + if (err) { + xchg(&link->link.prog, old_prog); + bpf_cgroup_storages_assign(pl->storage, old_storage); + bpf_cgroup_storages_free(new_storage); + cgrp->bpf.revisions[atype] -=3D 1; + return err; + } + bpf_prog_put(old_prog); + bpf_cgroup_storages_link(new_storage, cgrp, link->link.attach_type); return 0; } =20 --=20 2.34.1