From nobody Mon Sep 28 20:05:41 2026 Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (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 C4AC33E3176 for ; Tue, 18 Aug 2026 06:11:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787033503; cv=none; b=nCQBh65Hr6WyKEJUdS0nlop1AcjlelL/+ghvc1WVu1hSHKzYYiZhlZrTlDD2RN7BYZPt2Dz1h3eTGTFBXCS3pTX8XQyr0pHNmQYEo6kyteAXy2C6pk3lYcB94pzvojhKdIQOyuncF5+v5bPhuaa4bMapQeAyf2wvBa4gFaY1i1E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787033503; c=relaxed/simple; bh=EiTxNmLl+X9b9Y4H9T9jDRdn/xt7Cayy26DXOTx5hf8=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=s0REbkj0VLluTANz747EzlxlqO6cEkFpJhg5nq99c+1XZWN/GgLgDlNmlcOZFVLWdL2SMPe6sNOnPeyoCEgGJrhi0/7m4xkd9GVAdRDk4MfDjfe7B8hPjd41WcWQstIbjC3y9UEtMb2/ZTEyY5gyltrd7qfTiX4O0VdFFA4RSz4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Fbv6zsw4; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Fbv6zsw4" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-2d58efc7356so22380595ad.1 for ; Mon, 17 Aug 2026 23:11:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787033501; x=1787638301; 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=Edwx/E9+bRKmpGkg3wu9j7fjMN0VuqfNhhOccxzRCpY=; b=Fbv6zsw4UEXtchMsEb03qzSmmQPw7FdrQUWe2HqtWrWES1twaZbKD2aT4Q84VUW3Z2 Du848dyhyzU1omKSNQCGqfOWjXt4tekx0FOoZGiIYujxqLm11QSm1C3ZjYsrWfY1i39C 5xT1u2bbJ4rzJYihS06w8DZ/DRQD/bDkBjGCN/8dFYAmzJAODrAY3UQk5AJrdZ/7K9Db l60eQxHQySfCjBXCdlq9ljgMUZbVeAITxV1z67GV8oWvwXPJ6u81KRWF515TaarDioRo 9lCGgh+oXd2R9bkLKM1A6oCTISEvgxuUsMJ1Tr6lkEvZVYnSbNXbt7O3KhEYTLV6djUY vg0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787033501; x=1787638301; 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=Edwx/E9+bRKmpGkg3wu9j7fjMN0VuqfNhhOccxzRCpY=; b=P251ddRbujhCE/DNuEwWB9Qrai5bEV5c+AoeU4yTXpyXwFWd3kDfmAken7isF24/u7 VGKH+rP2ffVCO7a69jF99THnVV7QOP1Wq7J3MdZbPndT8XAQOJBIA0M+uQOq9lCmGcDa Ru5t3LhDmYmkueTaDvINup6PABCs24aP90Ka1fHo02H7dEZRbKq8ePLP1Hk13Ebq1w91 lyfptKIKPSxqH1BMVHPgIXfZsbB6dVFs2WeApnRmGdvvfkC7cAL9iMJ3IbQoC1J9Ck6N gIJKYGfxrW5iKeXaPZ2IhjCR45oZmP0C0NW0WOIUEu2UdqPDIodkS17m0Lm/LDUJGjAj 5gxA== X-Forwarded-Encrypted: i=1; AHgh+RqtCnw178btsQ/qV13zSVIjM5Tc+4t8Y6nQHwCS9Ls/FTsj5MVmQDP5wn1Lhr/Xy4ryNBI8S6HkXuavFmc=@vger.kernel.org X-Gm-Message-State: AOJu0YwF5MrkI9W76pj6xeo2rizTQoYGW/Lbd4bkT20AQCaftfXZ9o7h 7XdrrYNt3I+kjsv3CfBr2VoV1OVni/z/8YsDEDiSju5+KqtEQdM8H6y7 X-Gm-Gg: AR+sD12VA74NRwxLZjxub+WAK2KsV8302EUzkEuMTjVfyy3lBK3zJrWV/QD9MgcfQwS ga3GLq2GEkKoevIkuyiuIF+X52MiE6+LfHem/CFvq/6QfWXJil2bq5Lzc9N8zScaPG71cUO+L5b PjD4fll9DKJ3L/ocDBwZfg6/+LL25Y/IfmT7KcvQ9Li8kjQcCSNH+BE71C37KmdmByAJBGOkYR6 uknz/YF/GUo3tN7g23exTgfXyT1sNY0rkt2w3Ucx5pjcfmn6ujL0XOvfsWQ14FZ8kjv2hEMoT7Z bVe/hebYthKERVMDTFa3cW+FDpFyBxrtBNlKFCwXLlXe8uK6n1D4Y1C7XWVs1/n50PWlGFKjPWF K30tLFqEeSFiyekjQElXYgeqbnVtq02WYFOlKlrWrjeEMnYA46jgIjPZ7IAOZLA4wrtWuqequFB yy1xdg3LxRvR0ewi7Zr/utdqQZ+Qt2Yw7rR9q1HPs6yxrtq59VuUQDJi7Bd7ng0eMk//8F/LEY4 7TT7Ajs/IqM/uxYKA3FRjm7GvFtzPHiRcYTEWr8a5QMsnILakO6VuBPmDfOWQs= X-Received: by 2002:a17:902:d547:b0:2c9:df1b:e948 with SMTP id d9443c01a7336-2d3b0cdbdcbmr380270855ad.4.1787033500995; Mon, 17 Aug 2026 23:11:40 -0700 (PDT) Received: from secrnd-cstp.tailb7f510.ts.net ([125.131.91.97]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d5c1e54359sm10412685ad.49.2026.08.17.23.11.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 23:11:40 -0700 (PDT) From: Sanghyun Park To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , bpf@vger.kernel.org Cc: Sanghyun Park , John Fastabend , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Ihor Solodrai , Stanislav Fomichev , Pu Lehui , linux-kernel@vger.kernel.org Subject: [PATCH bpf-next v2] bpf: Fix stack out-of-bounds write in cgroup link update Date: Tue, 18 Aug 2026 15:10:21 +0900 Message-ID: <20260818061021.2551771-2-sanghyun.park.cnu@gmail.com> X-Mailer: git-send-email 2.48.1 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 Content-Type: text/plain; charset="utf-8" The cgroup link update path checks only the program type. Several cgroup hooks share a type while using different runtime contexts or verifier contracts. A UDP6 sock_addr program can therefore replace a UDP4 program and write beyond the four-byte ipc.addr context into adjacent fields of the stack-local struct ipcm_cookie. The same omission lets an LSM_MAC program replace an LSM_CGROUP program despite the incompatible return semantics. Validate replacement programs against the link attach type. Use the existing per-type rules where applicable, and compare LSM expected_attach_type explicitly because both flavors share BPF_PROG_TYPE_LSM. Preserve legacy non-enforcing CGROUP_SKB ingress/egress updates. CGROUP_SKB programs do not require CAP_NET_ADMIN when loaded. That permission is checked when the program is attached. Once the link exists, updates are controlled through its FD, so BPF_LINK_UPDATE does not check CAP_NET_ADMIN again. Keep this behavior and only validate the attach type during link update. Fixes: 0c991ebc8c69 ("bpf: Implement bpf_prog replacement for an active bpf= _cgroup_link") Signed-off-by: Sanghyun Park --- v2: - Extend validation from cgroup sock_addr programs to all cgroup program types, including exact LSM attach flavors. - Preserve legacy CGROUP_SKB ingress/egress replacement compatibility. - Keep the CGROUP_SKB CAP_NET_ADMIN check on attach, not link update. v1: https://lore.kernel.org/r/20260805052858.2390918-3-sanghyun.park.cnu@gm= ail.com --- kernel/bpf/syscall.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 8d111da886553c..de7a8b46814648 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -4462,7 +4462,8 @@ attach_type_to_prog_type(enum bpf_attach_type attach_= type) } =20 static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, - enum bpf_attach_type attach_type) + enum bpf_attach_type attach_type, + bool check_cap_net_admin) { enum bpf_prog_type ptype; =20 @@ -4473,7 +4474,8 @@ static int bpf_prog_attach_check_attach_type(const st= ruct bpf_prog *prog, case BPF_PROG_TYPE_SK_LOOKUP: return attach_type =3D=3D prog->expected_attach_type ? 0 : -EINVAL; case BPF_PROG_TYPE_CGROUP_SKB: - if (!bpf_token_capable(prog->aux->token, CAP_NET_ADMIN)) + if (check_cap_net_admin && + !bpf_token_capable(prog->aux->token, CAP_NET_ADMIN)) /* cg-skb progs can be loaded by unpriv user. * check permissions at attach time. */ @@ -4596,7 +4598,7 @@ static int bpf_prog_attach(const union bpf_attr *attr) if (IS_ERR(prog)) return PTR_ERR(prog); =20 - if (bpf_prog_attach_check_attach_type(prog, attr->attach_type)) { + if (bpf_prog_attach_check_attach_type(prog, attr->attach_type, true)) { bpf_prog_put(prog); return -EINVAL; } @@ -5797,7 +5799,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t= uattr) return PTR_ERR(prog); =20 ret =3D bpf_prog_attach_check_attach_type(prog, - attr->link_create.attach_type); + attr->link_create.attach_type, + true); if (ret) goto out; =20 @@ -5922,6 +5925,7 @@ static int link_update(union bpf_attr *attr) { struct bpf_prog *old_prog =3D NULL, *new_prog; struct bpf_link *link; + enum bpf_attach_type atype; u32 flags; int ret; =20 @@ -5959,6 +5963,22 @@ static int link_update(union bpf_attr *attr) goto out_put_progs; } =20 + if (link->type =3D=3D BPF_LINK_TYPE_CGROUP) { + atype =3D link->attach_type; + /* + * BPF_LSM_MAC and BPF_LSM_CGROUP share BPF_PROG_TYPE_LSM, so + * the helper's default prog-type check cannot distinguish them. + */ + if (new_prog->type =3D=3D BPF_PROG_TYPE_LSM && + new_prog->expected_attach_type !=3D atype) + ret =3D -EINVAL; + else + ret =3D bpf_prog_attach_check_attach_type(new_prog, atype, + false); + if (ret) + goto out_put_progs; + } + if (link->ops->update_prog) ret =3D link->ops->update_prog(link, new_prog, old_prog); else