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 5D22235AC31; Sat, 12 Sep 2026 18:35:04 +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=1789238105; cv=none; b=C9b48eLmg31IAmPYVfLxYiYcBHmquiRhY4YRLtwWAGe8QY91jP7E+2p83H2x5fX0mnH474oWGY9p9WeK9YC3598QxBwUYrsUF18dVevP/1sNlF4idne1+8L6B0ejjrcDxGsz+7k33xqWNy99qJr8Gq5R4/W6AA7UFy/+Ex+a6kw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789238105; c=relaxed/simple; bh=xB56Jiy01lOkupKSpfcPKpMSqxChLJIZewt2s3Jn+IE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s8AlGi4yQ+ktB5z+iykPYTEOEWxTnqq3QIs6tQeg1R23zA3CMy3VuAql/lDIQWdnlLOAptgCSsuhcbNfw2PPmoCYKHyclvcMDTRv412z2tI55+m4BDb+y33IMsM+leXw8510fotphdTa/ki7Lo/aKB/D8npPk/QJzW0YjnLPGqc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=PSyczKoz; 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="PSyczKoz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E4C211F000FF; Sat, 12 Sep 2026 18:35:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1789238103; bh=mfXJ8HEW1wdecFhBsIBpVR+cLAXqy4vI0ub65zgcwMA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=PSyczKozX7raIPDJEKpeb8GjaYSWrJalpcjO6z6eAdtZYc8559VknFeM4NUNc4hGw Su/TkBIyPwsyhiCvijnnLdeV7I7UGa8H8FMO/FRDO225MUsSxK2KZnSf7mDrNowX4U AdkpkRAT4EqcfRTinGTaedbv/jfVcVBVdcmQyALI= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Yinhao Hu , Kaiyan Mei , Dongliang Mu , Daniel Borkmann , Alexei Starovoitov , Sasha Levin , "Miguel Gazquez (Schneider Electric)" Subject: [PATCH 5.15 392/935] bpf: Enforce expected_attach_type for tailcall compatibility Date: Sat, 12 Sep 2026 08:57:02 +0200 Message-ID: <20260912065535.813855831@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260912065526.833703348@linuxfoundation.org> References: <20260912065526.833703348@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-Transfer-Encoding: 8bit 5.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Daniel Borkmann [ Upstream commit 4540aed51b12bc13364149bf95f6ecef013197c0 ] Yinhao et al. recently reported: Our fuzzer tool discovered an uninitialized pointer issue in the bpf_prog_test_run_xdp() function within the Linux kernel's BPF subsystem. This leads to a NULL pointer dereference when a BPF program attempts to deference the txq member of struct xdp_buff object. The test initializes two programs of BPF_PROG_TYPE_XDP: progA acts as the entry point for bpf_prog_test_run_xdp() and its expected_attach_type can neither be of be BPF_XDP_DEVMAP nor BPF_XDP_CPUMAP. progA calls into a slot of a tailcall map it owns. progB's expected_attach_type must be BPF_XDP_DEVMAP to pass xdp_is_valid_access() validation. The program returns struct xdp_md's egress_ifindex, and the latter is only allowed to be accessed under mentioned expected_attach_type. progB is then inserted into the tailcall which progA calls. The underlying issue goes beyond XDP though. Another example are programs of type BPF_PROG_TYPE_CGROUP_SOCK_ADDR. sock_addr_is_valid_access() as well as sock_addr_func_proto() have different logic depending on the programs' expected_attach_type. Similarly, a program attached to BPF_CGROUP_INET4_GETPEERNAME should not be allowed doing a tailcall into a program which calls bpf_bind() out of BPF which is only enabled for BPF_CGROUP_INET4_CONNECT. In short, specifying expected_attach_type allows to open up additional functionality or restrictions beyond what the basic bpf_prog_type enables. The use of tailcalls must not violate these constraints. Fix it by enforcing expected_attach_type in __bpf_prog_map_compatible(). Note that we only enforce this for tailcall maps, but not for BPF devmaps or cpumaps: There, the programs are invoked through dev_map_bpf_prog_run*() and cpu_map_bpf_prog_run*() which set up a new environment / context and therefore these situations are not prone to this issue. Fixes: 5e43f899b03a ("bpf: Check attach type at prog load time") Reported-by: Yinhao Hu Reported-by: Kaiyan Mei Reviewed-by: Dongliang Mu Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/r/20250926171201.188490-1-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Signed-off-by: Miguel Gazquez (Schneider Electric) Signed-off-by: Sasha Levin --- include/linux/bpf.h | 1 + kernel/bpf/core.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index ed42bac04a790..e9081b1ec4367 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -259,6 +259,7 @@ struct bpf_map_owner { bool xdp_has_frags; u64 storage_cookie[MAX_BPF_CGROUP_STORAGE_TYPE]; const struct btf_type *attach_func_proto; + enum bpf_attach_type expected_attach_type; }; struct bpf_map { diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index ac921214059f4..bbf95bc2d4089 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -1854,6 +1854,7 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map, map->owner->jited = fp->jited; /* Note: xdp_has_frags doesn't exist in aux yet in our branch */ /* map->owner->xdp_has_frags = aux->xdp_has_frags; */ + map->owner->expected_attach_type = fp->expected_attach_type; map->owner->attach_func_proto = aux->attach_func_proto; for_each_cgroup_storage_type(i) { map->owner->storage_cookie[i] = @@ -1866,6 +1867,10 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map, map->owner->jited == fp->jited; /* Note: xdp_has_frags check would go here when available */ /* && map->owner->xdp_has_frags == aux->xdp_has_frags; */ + if (ret && + map->map_type == BPF_MAP_TYPE_PROG_ARRAY && + map->owner->expected_attach_type != fp->expected_attach_type) + ret = false; for_each_cgroup_storage_type(i) { if (!ret) break; -- 2.53.0