From: Leon Hwang <leon.hwang@linux.dev>
To: bpf@vger.kernel.org
Cc: "Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Song Liu" <song@kernel.org>,
"Yonghong Song" <yonghong.song@linux.dev>,
"John Fastabend" <john.fastabend@gmail.com>,
"KP Singh" <kpsingh@kernel.org>,
"Stanislav Fomichev" <sdf@fomichev.me>,
"Hao Luo" <haoluo@google.com>, "Jiri Olsa" <jolsa@kernel.org>,
"Shuah Khan" <shuah@kernel.org>,
"Feng Yang" <yangfeng@kylinos.cn>,
"Leon Hwang" <leon.hwang@linux.dev>,
"Menglong Dong" <menglong8.dong@gmail.com>,
"Puranjay Mohan" <puranjay@kernel.org>,
"Björn Töpel" <bjorn@kernel.org>, "Pu Lehui" <pulehui@huawei.com>,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
netdev@vger.kernel.org, kernel-patches-bot@fb.com
Subject: [PATCH bpf-next v2 4/6] bpf: Disallow !call_get_func_ip progs tail-calling call_get_func_ip progs
Date: Mon, 2 Mar 2026 23:03:40 +0800 [thread overview]
Message-ID: <20260302150342.55709-5-leon.hwang@linux.dev> (raw)
In-Reply-To: <20260302150342.55709-1-leon.hwang@linux.dev>
Trampoline-based tracing programs that call bpf_get_func_ip() rely on
the func IP stored on the stack. Mixing !call_get_func_ip progs with
call_get_func_ip progs via tail calls could break this assumption.
To address this, reject the combination of !call_get_func_ip progs with
call_get_func_ip progs in bpf_map_owner_matches(), which prevents the
tail callee from getting a bogus func IP.
Also reject call_get_func_ip mismatches during initialization to
prevent bypassing the above restriction.
Without this check, the above restriction can be bypassed as follows.
struct {
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
__uint(max_entries, 1);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(__u32));
} jmp_table SEC(".maps");
SEC("?fentry")
int BPF_PROG(prog_a)
{
bpf_printk("FUNC IP: 0x%llx\n", bpf_get_func_ip());
bpf_tail_call_static(ctx, &jmp_table, 0);
return 0;
}
SEC("?fentry")
int BPF_PROG(prog_b)
{
bpf_tail_call_static(ctx, &jmp_table, 0);
return 0;
}
The jmp_table is shared between prog_a and prog_b.
* Load prog_a first.
At this point, owner->call_get_func_ip=true.
* Load prog_b next.
At this point, prog_b passes the compatibility check.
* Add prog_a to jmp_table.
* Attach prog_b to a kernel function.
When the kernel function runs, prog_a will get a bogus func IP because
no func IP is prepared on the trampoline stack.
Fixes: 1e37392cccde ("bpf: Enable BPF_TRAMP_F_IP_ARG for trampolines with call_get_func_ip")
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/bpf.h | 1 +
kernel/bpf/core.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index dbafed52b2ba..fb978650b169 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -289,6 +289,7 @@ struct bpf_map_owner {
u32 xdp_has_frags:1;
u32 sleepable:1;
u32 kprobe_write_ctx:1;
+ u32 call_get_func_ip:1;
u64 storage_cookie[MAX_BPF_CGROUP_STORAGE_TYPE];
const struct btf_type *attach_func_proto;
enum bpf_attach_type expected_attach_type;
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 121a697d4da5..1b88878fe5c5 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2391,6 +2391,7 @@ static void bpf_map_owner_init(struct bpf_map_owner *owner, const struct bpf_pro
owner->xdp_has_frags = aux->xdp_has_frags;
owner->sleepable = fp->sleepable;
owner->kprobe_write_ctx = aux->kprobe_write_ctx;
+ owner->call_get_func_ip = fp->call_get_func_ip;
owner->expected_attach_type = fp->expected_attach_type;
owner->attach_func_proto = aux->attach_func_proto;
for_each_cgroup_storage_type(i)
@@ -2422,11 +2423,17 @@ static bool bpf_map_owner_matches(const struct bpf_map *map, const struct bpf_pr
case BPF_MAP_OWNER_MATCH_FOR_INIT:
if (owner->kprobe_write_ctx != aux->kprobe_write_ctx)
return false;
+ if (owner->call_get_func_ip != fp->call_get_func_ip)
+ return false;
break;
case BPF_MAP_OWNER_MATCH_FOR_UPDATE:
if (!owner->kprobe_write_ctx && aux->kprobe_write_ctx)
return false;
+ if (bpf_prog_has_trampoline(fp)) {
+ if (!owner->call_get_func_ip && fp->call_get_func_ip)
+ return false;
+ }
break;
}
--
2.52.0
next prev parent reply other threads:[~2026-03-02 15:05 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-02 15:03 [PATCH bpf-next v2 0/6] bpf: Enhance __bpf_prog_map_compatible() Leon Hwang
2026-03-02 15:03 ` [PATCH bpf-next v2 1/6] bpf: Add fsession to verbose log in check_get_func_ip() Leon Hwang
2026-03-02 15:03 ` [PATCH bpf-next v2 2/6] bpf: Factor out bpf_map_owner_[init,matches]() helpers Leon Hwang
2026-03-02 15:03 ` [PATCH bpf-next v2 3/6] bpf: Disallow !kprobe_write_ctx progs tail-calling kprobe_write_ctx progs Leon Hwang
2026-03-02 15:53 ` bot+bpf-ci
2026-03-03 1:44 ` Leon Hwang
2026-03-02 15:03 ` Leon Hwang [this message]
2026-03-02 15:53 ` [PATCH bpf-next v2 4/6] bpf: Disallow !call_get_func_ip progs tail-calling call_get_func_ip progs bot+bpf-ci
2026-03-03 1:47 ` Leon Hwang
2026-03-02 15:03 ` [PATCH bpf-next v2 5/6] bpf: Disallow !call_session_cookie progs tail-calling call_session_cookie progs Leon Hwang
2026-03-02 15:03 ` [PATCH bpf-next v2 6/6] selftests/bpf: Add tests to verify prog_array map compatibility Leon Hwang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260302150342.55709-5-leon.hwang@linux.dev \
--to=leon.hwang@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bjorn@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kernel-patches-bot@fb.com \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=menglong8.dong@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pulehui@huawei.com \
--cc=puranjay@kernel.org \
--cc=sdf@fomichev.me \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=yangfeng@kylinos.cn \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.