From nobody Fri Jul 24 23:31:28 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 AE9B12DEA74; Wed, 22 Jul 2026 07:18:57 +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=1784704739; cv=none; b=CrGl5dR5DoqWq5XJotLKfsTntXUm9usLI00Oc2eN6ooSjCpQA/t0RzLiHJQ1y9E4hPWDbfQizBP9Am7YjKXsU0FFK88Vu4UO3hado22VCJ8LU7ugwaYM3Wzb0xlrhGSqr5msfWSxWlIWYXhZPsScXaw5OviOeey3rbcKMP8jx2c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704739; c=relaxed/simple; bh=0ZE5l63EQjM4Y77A3+E+e7nz/PBfL4JJWnRvK9TZI8o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NAjS4O6BmiQ4nqq/mzqvF26wKANEkH3UrlDjQQTR+UKBctkkuWAWO1vsyoQ9R0/UCS7V3myQdUfwpGHcQeZLDgwnf0A5trfszQh4ZbVXKfPEiZlm6Hyj/gkuAn7CxbEHPr4YqovuZmm1kyObG20xe2M4QMEKbCy2lfKHWM/+GoU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=none 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=none smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4h4lwL6FQxzYQttH; Wed, 22 Jul 2026 15:18:26 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 811A040570; Wed, 22 Jul 2026 15:18:55 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgCHl3PfbmBqGBB_CA--.17870S3; Wed, 22 Jul 2026 15:18:55 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, Amery Hung , Emil Tsalapatis , Mykyta Yatsenko Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Pu Lehui , Pu Lehui Subject: [PATCH bpf v6 1/4] bpf: Fix potential UAF in bpf_netns_link_update_prog Date: Wed, 22 Jul 2026 07:23:23 +0000 Message-Id: <20260722072326.1545677-2-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260722072326.1545677-1-pulehui@huaweicloud.com> References: <20260722072326.1545677-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: cCh0CgCHl3PfbmBqGBB_CA--.17870S3 X-Coremail-Antispam: 1UD129KBjvJXoW7tr1xJw4kCF1Utr17uF48WFg_yoW8Cw4fpF y3Cr1DXw10krsF9F18X3WkuryrXFy0gr1UCr1DZ3W0gFyIqr1Fg34UurZ29rZY9FWqgFyS qa4jgr4Fqw1jva7anT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmY14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r4j6ryUM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UM2 8EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2Y2ka0x kIwI1lc7CjxVAaw2AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_ Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1V AY17CE14v26r4a6rW5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAI cVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42 IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIev Ja73UjIFyTuYvjTRAb10DUUUU 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 Reviewed-by: Amery Hung Reviewed-by: Emil Tsalapatis Signed-off-by: Pu Lehui --- 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 Fri Jul 24 23:31:28 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 AEADA372EF0; Wed, 22 Jul 2026 07:18:57 +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=1784704740; cv=none; b=J6WYHNDRTza/9SFO3MP8At7I1eGooVVKLXVFXGUuMwXOPjHf2W2+KDVe9SjJjyOCerN9NYAZ86lG1/Zr+E1mVGBOqlOI4h5dYVr3+z5rVWk7+o0aSIbKfRzRvXiS9TFxkafTo1m6J0OCoxtNoxF/BkKqa9gAG3/a+HDffO/6oos= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704740; c=relaxed/simple; bh=5p5KnCCkjhxaTDPY8p++gCJCVjU1e8U5eMnQBy4BZrY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=MHrYPfBnQHvSguoFluoz/8BbgFJHoU/bbn2rvJGhO6t2e8zFMXSpZ3yGLdAXApxRzNzxV1nfbUw7Q6l4gN8WymFXVBFv12RM+ysOdNt+EjQ938zOM/d4JT7Y9AAEB9tetSTlz5QzcdBqesEOXe50U8Q0MJkBtSdXpDnYVrnoBXA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=none 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=none smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4h4lwL70m6zYQtth; Wed, 22 Jul 2026 15:18:26 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 9AF6F4061C; Wed, 22 Jul 2026 15:18:55 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgCHl3PfbmBqGBB_CA--.17870S4; Wed, 22 Jul 2026 15:18:55 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, Amery Hung , Emil Tsalapatis , Mykyta Yatsenko Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Pu Lehui , Pu Lehui Subject: [PATCH bpf v6 2/4] bpf: Fix UAF due to missing link type check in mprog Date: Wed, 22 Jul 2026 07:23:24 +0000 Message-Id: <20260722072326.1545677-3-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260722072326.1545677-1-pulehui@huaweicloud.com> References: <20260722072326.1545677-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: cCh0CgCHl3PfbmBqGBB_CA--.17870S4 X-Coremail-Antispam: 1UD129KBjvJXoWfJF4rGFWfGF45Ww48AF1fJFb_yoWDXF1xpF WfJFyvyry0q3y7XF40qa18A3y5uF40gr17CFy5K34Y9FnF9Fn2qFy5WrWYy34YyrZ8CFs7 ZF1Utr98XryUXrUanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jryl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0D M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjx v20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1l F7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2 IY04v7MxkF7I0En4kS14v26r4a6rW5MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVW8ZVWrXwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF 0xvE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMI IF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnI WIevJa73UjIFyTuYvjTRRCJPDUUUU 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 doing 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 /* non-netkit or non-tcx link */ link =3D bpf_link_get_from_fd(id_or_fd); BPF_LINK_UPDATE on relative link ... old_prog =3D xchg(&link->link.pro= g, new_prog); bpf_prog_put(old_prog); if (type && link->prog->type !=3D type) <-- trigger UAF The reason for the UAF is that each subsystem provides its own protection for link->prog. Since there is no cross subsystem protection (if not considering the RCU of prog tear down), dereferencing the prog of an anchor link that does not belong to the current subsystem is not safe: it may have been freed. Therefore, we need to validate link->type to reject foreign anchors. Fix this by strictly validating link->type in bpf_mprog_link against the expected link type. mprog APIs is also adjusted to accept and pass down the expected link type. Meanwhile, add a comment explaining that when ptype =3D=3D UNSPEC in bpf_mprog_detach, it acts as a wildcard. Fixes: 053c8e1f235d ("bpf: Add generic attach/detach/query API for multi-pr= ogs") Reported-by: Sashiko Reviewed-by: Amery Hung Signed-off-by: Pu Lehui --- drivers/net/netkit.c | 13 ++++++------- include/linux/bpf_mprog.h | 6 ++++-- kernel/bpf/mprog.c | 23 ++++++++++++++--------- kernel/bpf/tcx.c | 13 ++++++------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c index a3931cd82132..99ddf2befb23 100644 --- a/drivers/net/netkit.c +++ b/drivers/net/netkit.c @@ -768,7 +768,7 @@ int netkit_prog_attach(const union bpf_attr *attr, stru= ct bpf_prog *prog) } ret =3D bpf_mprog_attach(entry, &entry_new, prog, NULL, replace_prog, attr->attach_flags, attr->relative_fd, - attr->expected_revision); + attr->expected_revision, BPF_LINK_TYPE_NETKIT); if (!ret) { if (entry !=3D entry_new) { netkit_entry_update(dev, entry_new); @@ -802,7 +802,7 @@ int netkit_prog_detach(const union bpf_attr *attr, stru= ct bpf_prog *prog) goto out; } ret =3D bpf_mprog_detach(entry, &entry_new, prog, NULL, attr->attach_flag= s, - attr->relative_fd, attr->expected_revision); + attr->relative_fd, attr->expected_revision, BPF_LINK_TYPE_NETKIT= ); if (!ret) { if (!bpf_mprog_total(entry_new)) entry_new =3D NULL; @@ -850,7 +850,7 @@ static int netkit_link_prog_attach(struct bpf_link *lin= k, u32 flags, ASSERT_RTNL(); entry =3D netkit_entry_fetch(dev, true); ret =3D bpf_mprog_attach(entry, &entry_new, link->prog, link, NULL, flags, - id_or_fd, revision); + id_or_fd, revision, BPF_LINK_TYPE_NETKIT); if (!ret) { if (entry !=3D entry_new) { netkit_entry_update(dev, entry_new); @@ -877,7 +877,7 @@ static void netkit_link_release(struct bpf_link *link) ret =3D -ENOENT; goto out; } - ret =3D bpf_mprog_detach(entry, &entry_new, link->prog, link, 0, 0, 0); + ret =3D bpf_mprog_detach(entry, &entry_new, link->prog, link, 0, 0, 0, BP= F_LINK_TYPE_NETKIT); if (!ret) { if (!bpf_mprog_total(entry_new)) entry_new =3D NULL; @@ -919,9 +919,8 @@ static int netkit_link_update(struct bpf_link *link, st= ruct bpf_prog *nprog, ret =3D -ENOENT; goto out; } - ret =3D bpf_mprog_attach(entry, &entry_new, nprog, link, oprog, - BPF_F_REPLACE | BPF_F_ID, - link->prog->aux->id, 0); + ret =3D bpf_mprog_attach(entry, &entry_new, nprog, link, oprog, BPF_F_REP= LACE | BPF_F_ID, + link->prog->aux->id, 0, BPF_LINK_TYPE_NETKIT); if (!ret) { WARN_ON_ONCE(entry !=3D entry_new); oprog =3D xchg(&link->prog, nprog); diff --git a/include/linux/bpf_mprog.h b/include/linux/bpf_mprog.h index 0b9f4caeeb0a..1fbe1a923968 100644 --- a/include/linux/bpf_mprog.h +++ b/include/linux/bpf_mprog.h @@ -321,12 +321,14 @@ int bpf_mprog_attach(struct bpf_mprog_entry *entry, struct bpf_mprog_entry **entry_new, struct bpf_prog *prog_new, struct bpf_link *link, struct bpf_prog *prog_old, - u32 flags, u32 id_or_fd, u64 revision); + u32 flags, u32 id_or_fd, u64 revision, + enum bpf_link_type expected_link_type); =20 int bpf_mprog_detach(struct bpf_mprog_entry *entry, struct bpf_mprog_entry **entry_new, struct bpf_prog *prog, struct bpf_link *link, - u32 flags, u32 id_or_fd, u64 revision); + u32 flags, u32 id_or_fd, u64 revision, + enum bpf_link_type expected_link_type); =20 int bpf_mprog_query(const union bpf_attr *attr, union bpf_attr __user *uat= tr, struct bpf_mprog_entry *entry); diff --git a/kernel/bpf/mprog.c b/kernel/bpf/mprog.c index 1394168062e8..b4a1b35ff569 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) @@ -226,7 +227,8 @@ int bpf_mprog_attach(struct bpf_mprog_entry *entry, struct bpf_mprog_entry **entry_new, struct bpf_prog *prog_new, struct bpf_link *link, struct bpf_prog *prog_old, - u32 flags, u32 id_or_fd, u64 revision) + u32 flags, u32 id_or_fd, u64 revision, + enum bpf_link_type expected_link_type) { struct bpf_tuple rtuple, ntuple =3D { .prog =3D prog_new, @@ -243,6 +245,7 @@ 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, + expected_link_type, prog_new->type); if (ret) return ret; @@ -328,7 +331,8 @@ static int bpf_mprog_fetch(struct bpf_mprog_entry *entr= y, int bpf_mprog_detach(struct bpf_mprog_entry *entry, struct bpf_mprog_entry **entry_new, struct bpf_prog *prog, struct bpf_link *link, - u32 flags, u32 id_or_fd, u64 revision) + u32 flags, u32 id_or_fd, u64 revision, + enum bpf_link_type expected_link_type) { struct bpf_tuple rtuple, dtuple =3D { .prog =3D prog, @@ -343,8 +347,9 @@ 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, - prog ? prog->type : - BPF_PROG_TYPE_UNSPEC); + expected_link_type, + /* Use UNSPEC as wildcard when prog is NULL */ + prog ? prog->type : BPF_PROG_TYPE_UNSPEC); if (ret) return ret; if (dtuple.prog) { diff --git a/kernel/bpf/tcx.c b/kernel/bpf/tcx.c index 02db0113b8e7..f208cef13a98 100644 --- a/kernel/bpf/tcx.c +++ b/kernel/bpf/tcx.c @@ -38,7 +38,7 @@ int tcx_prog_attach(const union bpf_attr *attr, struct bp= f_prog *prog) } ret =3D bpf_mprog_attach(entry, &entry_new, prog, NULL, replace_prog, attr->attach_flags, attr->relative_fd, - attr->expected_revision); + attr->expected_revision, BPF_LINK_TYPE_TCX); if (!ret) { if (entry !=3D entry_new) { tcx_entry_update(dev, entry_new, ingress); @@ -76,7 +76,7 @@ int tcx_prog_detach(const union bpf_attr *attr, struct bp= f_prog *prog) goto out; } ret =3D bpf_mprog_detach(entry, &entry_new, prog, NULL, attr->attach_flag= s, - attr->relative_fd, attr->expected_revision); + attr->relative_fd, attr->expected_revision, BPF_LINK_TYPE_TCX); if (!ret) { if (!tcx_entry_is_active(entry_new)) entry_new =3D NULL; @@ -152,7 +152,7 @@ static int tcx_link_prog_attach(struct bpf_link *link, = u32 flags, u32 id_or_fd, if (!entry) return -ENOMEM; ret =3D bpf_mprog_attach(entry, &entry_new, link->prog, link, NULL, flags, - id_or_fd, revision); + id_or_fd, revision, BPF_LINK_TYPE_TCX); if (!ret) { if (entry !=3D entry_new) { tcx_entry_update(dev, entry_new, ingress); @@ -183,7 +183,7 @@ static void tcx_link_release(struct bpf_link *link) ret =3D -ENOENT; goto out; } - ret =3D bpf_mprog_detach(entry, &entry_new, link->prog, link, 0, 0, 0); + ret =3D bpf_mprog_detach(entry, &entry_new, link->prog, link, 0, 0, 0, BP= F_LINK_TYPE_TCX); if (!ret) { if (!tcx_entry_is_active(entry_new)) entry_new =3D NULL; @@ -229,9 +229,8 @@ static int tcx_link_update(struct bpf_link *link, struc= t bpf_prog *nprog, ret =3D -ENOENT; goto out; } - ret =3D bpf_mprog_attach(entry, &entry_new, nprog, link, oprog, - BPF_F_REPLACE | BPF_F_ID, - link->prog->aux->id, 0); + ret =3D bpf_mprog_attach(entry, &entry_new, nprog, link, oprog, BPF_F_REP= LACE | BPF_F_ID, + link->prog->aux->id, 0, BPF_LINK_TYPE_TCX); if (!ret) { WARN_ON_ONCE(entry !=3D entry_new); oprog =3D xchg(&link->prog, nprog); --=20 2.34.1 From nobody Fri Jul 24 23:31:28 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 55E15397E64; Wed, 22 Jul 2026 07:18:58 +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=1784704744; cv=none; b=edfVPO+5iQWrmYJ72tFESIBar1LKOXOHzRvlWyWGsuskRhhZo4nB0vbomq9ROEgGTCSagI5lt4mqAw7N5DOgEMq/gk6TV9F5RYAxV69Cc+60NDQ6xqNRCz7WkbuUsP94EOA3yIyNahvg6hGQRShaHZHPlpWz7O435X/L3pxzA5k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704744; c=relaxed/simple; bh=vJDOeHO4DMMMzj3MOJQJSBfceD1u1PVO8B9U0BnSy28=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dtixL9UNeEyFbYH08s6c+nNxwSwecEDrm4DSqfX9AF6ymBheHIwGRIlOD3zSJQnyA1CsH7XzYMNcd6jxQR1Nkv98OSU8N9H5ub4WM8EicHf2yd74zyxgL80r7ELxin8VMmtTq416thZRn4OkIymiH7xgtLosIu/B4BygLkHmlRE= 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 4h4lw42KPJzKHMTh; Wed, 22 Jul 2026 15:18:12 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 9FEE44056F; Wed, 22 Jul 2026 15:18:55 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgCHl3PfbmBqGBB_CA--.17870S5; Wed, 22 Jul 2026 15:18:55 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, Amery Hung , Emil Tsalapatis , Mykyta Yatsenko Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Pu Lehui , Pu Lehui Subject: [PATCH bpf v6 3/4] bpf: Fix potential UAF when reading bpf link info Date: Wed, 22 Jul 2026 07:23:25 +0000 Message-Id: <20260722072326.1545677-4-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260722072326.1545677-1-pulehui@huaweicloud.com> References: <20260722072326.1545677-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: cCh0CgCHl3PfbmBqGBB_CA--.17870S5 X-Coremail-Antispam: 1UD129KBjvJXoWxJFyfGryUuF4UZF1xCFy5twb_yoW5ArW7pF W3G3Z8Ca1rWr4293WUXrWUZrySgF4xWFyUJF97W34FyF1aqrZYgFyUGrWfZr9IkFykGr1f X34jvFy5Jw17XFDanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JrWl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0D M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjx v20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1l F7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2 IY04v7MxkF7I0En4kS14v26r4a6rW5MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVW8ZVWrXwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF 0xvE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMI IF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnI WIevJa73UjIFyTuYvjfUUo7KUUUUU 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. Before dereferencing the prog, both normal RCU and RCU Tasks Trace read locks would normally be required, as BPF_LINK_TYPE_ITER supports both non-sleepable and sleepable progs. However, as commit 57b23c0f612d ("bpf: Retire rcu_trace_implies_rcu_gp()") clarifies, an RCU Tasks Trace grace period implies an RCU grace period, so holding only rcu_read_lock() is already sufficient. Fixes: 0c991ebc8c69 ("bpf: Implement bpf_prog replacement for an active bpf= _cgroup_link") Reported-by: Sashiko Reviewed-by: Emil Tsalapatis Reviewed-by: Amery Hung Signed-off-by: Pu Lehui --- kernel/bpf/syscall.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 6db306d23b47..cad986807d53 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,20 @@ static void bpf_link_show_fdinfo(struct seq_file *m= , struct file *filp) } seq_printf(m, "link_id:\t%u\n", link->id); =20 + 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(); + + 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 +5543,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 +5558,12 @@ 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; + + rcu_read_lock(); + prog =3D READ_ONCE(link->prog); + if (prog) + info.prog_id =3D prog->aux->id; + rcu_read_unlock(); =20 if (link->ops->fill_link_info) { err =3D link->ops->fill_link_info(link, &info); --=20 2.34.1 From nobody Fri Jul 24 23:31:28 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 AEB643845B3; Wed, 22 Jul 2026 07:18:57 +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=1784704740; cv=none; b=nD6N+8+7NvhAz8RpE+aJqFU3BOovpPVenX1p40b1dAmu1TRe7UmKEMZ54nA4RfW4izvWqkEMLOt0oOxd6TF6d5dy/r/Z0gceFl0j1evyxOFkRT+31eTPmzC4f+eAeAQL/aX864z3tVtXAEdNxd69trwUSs4QWcv1YyXnCvaPT5Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704740; c=relaxed/simple; bh=6kLDb/EkwL+x0uT2625WN0nWMVGKTy4T4ZBkAimrppQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZvWwnAXDuP1nV1rARQVgniSc9HPy4zTRFk3vBAcim+z1wcFrAt9ZCJpbldm+x7EbSAS9F2bDAgPIUPqZ7pDyVuQthERZ5S1GusdMcoFD8YPMQQ9t5QSEBTgeKgIaL3Z4ZSA+5+hxaN7Ej1NYeFmS2iTe0tr0UH3M9Jt5rA4cwCc= 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 4h4lwM0JPszYQttb; Wed, 22 Jul 2026 15:18:27 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id A72534070C; Wed, 22 Jul 2026 15:18:55 +0800 (CST) Received: from ultra.huawei.com (unknown [10.90.53.71]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgCHl3PfbmBqGBB_CA--.17870S6; Wed, 22 Jul 2026 15:18:55 +0800 (CST) From: Pu Lehui To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, Amery Hung , Emil Tsalapatis , Mykyta Yatsenko Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Yonghong Song , Song Liu , Jiri Olsa , Pu Lehui , Pu Lehui Subject: [PATCH bpf v6 4/4] bpf, cgroup: Fix storage null-ptr-deref after replacing prog Date: Wed, 22 Jul 2026 07:23:26 +0000 Message-Id: <20260722072326.1545677-5-pulehui@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260722072326.1545677-1-pulehui@huaweicloud.com> References: <20260722072326.1545677-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: cCh0CgCHl3PfbmBqGBB_CA--.17870S6 X-Coremail-Antispam: 1UD129KBjvJXoWxCF13ArW3Zw17Ar4DXFWrXwb_yoWrKw48pF 1kAwn8tw1UX39avF1kJ39FvF1rAa10qr1UKrZ8tw1Fkay7tayFg347CryYva43uF1DWr1f tw1YvF4jk3WjvFUanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmq14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl 6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x IIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_ Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8c xan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCj c4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4 CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryU MIIF0xvE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r 1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIY CTnIWIevJa73UjIFyTuYvjTRRyxRDUUUU 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") Reviewed-by: Amery Hung Signed-off-by: Pu Lehui --- 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