* [PATCH bpf-next 1/6] bpf: Use user_path_at for path resolution in uprobe_multi
2026-06-09 10:42 [PATCH bpf-next 0/6] bpf: Allow uprobe_multi binary specified by file descriptor Jiri Olsa
@ 2026-06-09 10:42 ` Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor Jiri Olsa
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 10:42 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Oleg Nesterov, Masami Hiramatsu
Resolve the uprobe_multi user path with user_path_at() instead of copying
the string with strndup_user() and passing it to kern_path(). This removes
the temporary allocation and keeps the lookup logic in one helper.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/trace/bpf_trace.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 90432f0fc2a8..970ce7bbf99e 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -3226,7 +3226,6 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
void __user *upath;
u32 flags, cnt, i;
struct path path;
- char *name;
pid_t pid;
int err;
@@ -3261,14 +3260,7 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
uref_ctr_offsets = u64_to_user_ptr(attr->link_create.uprobe_multi.ref_ctr_offsets);
ucookies = u64_to_user_ptr(attr->link_create.uprobe_multi.cookies);
- name = strndup_user(upath, PATH_MAX);
- if (IS_ERR(name)) {
- err = PTR_ERR(name);
- return err;
- }
-
- err = kern_path(name, LOOKUP_FOLLOW, &path);
- kfree(name);
+ err = user_path_at(AT_FDCWD, upath, LOOKUP_FOLLOW, &path);
if (err)
return err;
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor
2026-06-09 10:42 [PATCH bpf-next 0/6] bpf: Allow uprobe_multi binary specified by file descriptor Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 1/6] bpf: Use user_path_at for path resolution in uprobe_multi Jiri Olsa
@ 2026-06-09 10:42 ` Jiri Olsa
2026-06-09 10:57 ` sashiko-bot
` (2 more replies)
2026-06-09 10:42 ` [PATCH bpf-next 3/6] libbpf: Add path_fd to struct bpf_link_create_opts Jiri Olsa
` (3 subsequent siblings)
5 siblings, 3 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 10:42 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Oleg Nesterov, Masami Hiramatsu
Allow uprobe_multi link to identify the target binary by an already
opened file descriptor.
Adding new BPF_F_UPROBE_MULTI_PATH_FD flag and the path_fd field for
the attr.link_create.uprobe_multi struct.
When the flag is set, we resolve the target from path_fd, without the
flag, we keep the existing string path behavior.
I don't see a use case for supporting O_PATH file descriptors, because
we need need to read the binary first to get probes offsets, so I'm
using the CLASS(fd, f), which fails for O_PATH fds.
Assisted-by: Codex:GPT-5.4
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/uapi/linux/bpf.h | 7 ++++++-
kernel/bpf/syscall.c | 4 ++--
kernel/trace/bpf_trace.c | 37 +++++++++++++++++++++++++++-------
tools/include/uapi/linux/bpf.h | 7 ++++++-
4 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 11dd610fa5fa..89b36de5fdbb 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1327,7 +1327,11 @@ enum {
* BPF_TRACE_UPROBE_MULTI attach type to create return probe.
*/
enum {
- BPF_F_UPROBE_MULTI_RETURN = (1U << 0)
+ /* Get return uprobe. */
+ BPF_F_UPROBE_MULTI_RETURN = (1U << 0),
+
+ /* Get path from provided path_fd. */
+ BPF_F_UPROBE_MULTI_PATH_FD = (1U << 1),
};
/* link_create.netfilter.flags used in LINK_CREATE command for
@@ -1864,6 +1868,7 @@ union bpf_attr {
__u32 cnt;
__u32 flags;
__u32 pid;
+ __u32 path_fd;
} uprobe_multi;
struct {
union {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index d4188a992bd8..cef9bd6316a5 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3475,7 +3475,7 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)
seq_printf(m, "link_type:\t%s\n", link->flags == BPF_F_KPROBE_MULTI_RETURN ?
"kretprobe_multi" : "kprobe_multi");
else if (link->type == BPF_LINK_TYPE_UPROBE_MULTI)
- seq_printf(m, "link_type:\t%s\n", link->flags == BPF_F_UPROBE_MULTI_RETURN ?
+ seq_printf(m, "link_type:\t%s\n", link->flags & BPF_F_UPROBE_MULTI_RETURN ?
"uretprobe_multi" : "uprobe_multi");
else
seq_printf(m, "link_type:\t%s\n", bpf_link_type_strs[type]);
@@ -5835,7 +5835,7 @@ static int bpf_map_do_batch(const union bpf_attr *attr,
return err;
}
-#define BPF_LINK_CREATE_LAST_FIELD link_create.uprobe_multi.pid
+#define BPF_LINK_CREATE_LAST_FIELD link_create.uprobe_multi.path_fd
static int link_create(union bpf_attr *attr, bpfptr_t uattr)
{
struct bpf_prog *prog;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 970ce7bbf99e..4965006d58ee 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -23,6 +23,7 @@
#include <linux/sort.h>
#include <linux/key.h>
#include <linux/namei.h>
+#include <linux/file.h>
#include <net/bpf_sk_storage.h>
@@ -3240,29 +3241,51 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
return -EINVAL;
flags = attr->link_create.uprobe_multi.flags;
- if (flags & ~BPF_F_UPROBE_MULTI_RETURN)
+ if (flags & ~(BPF_F_UPROBE_MULTI_RETURN|BPF_F_UPROBE_MULTI_PATH_FD))
return -EINVAL;
/*
- * path, offsets and cnt are mandatory,
+ * offsets and cnt are mandatory,
* ref_ctr_offsets and cookies are optional
*/
- upath = u64_to_user_ptr(attr->link_create.uprobe_multi.path);
uoffsets = u64_to_user_ptr(attr->link_create.uprobe_multi.offsets);
cnt = attr->link_create.uprobe_multi.cnt;
pid = attr->link_create.uprobe_multi.pid;
- if (!upath || !uoffsets || !cnt || pid < 0)
+ if (!uoffsets || !cnt || pid < 0)
return -EINVAL;
if (cnt > MAX_UPROBE_MULTI_CNT)
return -E2BIG;
uref_ctr_offsets = u64_to_user_ptr(attr->link_create.uprobe_multi.ref_ctr_offsets);
ucookies = u64_to_user_ptr(attr->link_create.uprobe_multi.cookies);
+ upath = u64_to_user_ptr(attr->link_create.uprobe_multi.path);
- err = user_path_at(AT_FDCWD, upath, LOOKUP_FOLLOW, &path);
- if (err)
- return err;
+ if (flags & BPF_F_UPROBE_MULTI_PATH_FD) {
+ /*
+ * When BPF_F_UPROBE_MULTI_PATH_FD is set, the executable is identified
+ * by path_fd, and upath must be NULL.
+ */
+ if (upath)
+ return -EINVAL;
+
+ CLASS(fd, f)(attr->link_create.uprobe_multi.path_fd);
+ if (fd_empty(f))
+ return -EBADF;
+ path = fd_file(f)->f_path;
+ path_get(&path);
+ } else {
+ /*
+ * When BPF_F_UPROBE_MULTI_PATH_FD is not set, the path is resolved
+ * relative to the cwd (AT_FDCWD) or absolute using the upath string.
+ */
+ if (!upath)
+ return -EINVAL;
+
+ err = user_path_at(AT_FDCWD, upath, LOOKUP_FOLLOW, &path);
+ if (err)
+ return err;
+ }
if (!d_is_reg(path.dentry)) {
err = -EBADF;
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 11dd610fa5fa..89b36de5fdbb 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1327,7 +1327,11 @@ enum {
* BPF_TRACE_UPROBE_MULTI attach type to create return probe.
*/
enum {
- BPF_F_UPROBE_MULTI_RETURN = (1U << 0)
+ /* Get return uprobe. */
+ BPF_F_UPROBE_MULTI_RETURN = (1U << 0),
+
+ /* Get path from provided path_fd. */
+ BPF_F_UPROBE_MULTI_PATH_FD = (1U << 1),
};
/* link_create.netfilter.flags used in LINK_CREATE command for
@@ -1864,6 +1868,7 @@ union bpf_attr {
__u32 cnt;
__u32 flags;
__u32 pid;
+ __u32 path_fd;
} uprobe_multi;
struct {
union {
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor
2026-06-09 10:42 ` [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor Jiri Olsa
@ 2026-06-09 10:57 ` sashiko-bot
2026-06-09 13:23 ` Jiri Olsa
2026-06-09 11:17 ` bot+bpf-ci
2026-06-09 18:22 ` Alexei Starovoitov
2 siblings, 1 reply; 12+ messages in thread
From: sashiko-bot @ 2026-06-09 10:57 UTC (permalink / raw)
To: Jiri Olsa; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Missing strict zero-validation for the unused `path_fd` field when the `BPF_F_UPROBE_MULTI_PATH_FD` flag is not set.
- [Low] Mixing scope-based cleanup (`CLASS()`) with `goto`-based error handling in `bpf_uprobe_multi_link_attach`.
--
commit f7958ff1ce57c1ab456d3f134881a0081a58b8ed
Author: Jiri Olsa <jolsa@kernel.org>
bpf: Add support to specify uprobe_multi target via file descriptor
This commit adds the BPF_F_UPROBE_MULTI_PATH_FD flag to allow uprobe_multi
links to specify the target binary using an already opened file descriptor
instead of a path string.
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 970ce7bbf99e1..4965006d58ee6 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
[ ... ]
> @@ -3240,29 +3241,51 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
[ ... ]
> uref_ctr_offsets = u64_to_user_ptr(attr->link_create.uprobe_multi.ref_ctr_offsets);
> ucookies = u64_to_user_ptr(attr->link_create.uprobe_multi.cookies);
> + upath = u64_to_user_ptr(attr->link_create.uprobe_multi.path);
>
> - err = user_path_at(AT_FDCWD, upath, LOOKUP_FOLLOW, &path);
> - if (err)
> - return err;
> + if (flags & BPF_F_UPROBE_MULTI_PATH_FD) {
> + /*
> + * When BPF_F_UPROBE_MULTI_PATH_FD is set, the executable is identified
> + * by path_fd, and upath must be NULL.
> + */
> + if (upath)
> + return -EINVAL;
> +
> + CLASS(fd, f)(attr->link_create.uprobe_multi.path_fd);
[Severity: Low]
Does this code violate the cleanup subsystem guidelines by mixing scope-based
cleanup with goto-based error handling?
The bpf_uprobe_multi_link_attach() function relies heavily on goto labels
for error paths (e.g., error_path_put, error_free, error_unregister). The
kernel guidelines state that goto-based cleanup and scope-based cleanup
helpers (like CLASS) should never be mixed in the same function.
Should this function be fully converted to scope-based cleanup, or should it
use explicit fdget()/fdput() without CLASS() instead?
> + if (fd_empty(f))
> + return -EBADF;
> + path = fd_file(f)->f_path;
> + path_get(&path);
> + } else {
> + /*
> + * When BPF_F_UPROBE_MULTI_PATH_FD is not set, the path is resolved
> + * relative to the cwd (AT_FDCWD) or absolute using the upath string.
> + */
> + if (!upath)
> + return -EINVAL;
[Severity: Medium]
Should there be strict zero-validation for the unused path_fd field here?
When the BPF_F_UPROBE_MULTI_PATH_FD flag is not set, this branch is taken
and attr->link_create.uprobe_multi.path_fd is ignored without being
validated as zero.
If userspace passes uninitialized garbage in this field, it won't be
rejected. Could this break forward compatibility if path_fd needs to be
assigned a new meaning in the future?
> +
> + err = user_path_at(AT_FDCWD, upath, LOOKUP_FOLLOW, &path);
> + if (err)
> + return err;
> + }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260609104244.588321-1-jolsa@kernel.org?part=2
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor
2026-06-09 10:57 ` sashiko-bot
@ 2026-06-09 13:23 ` Jiri Olsa
0 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 13:23 UTC (permalink / raw)
To: sashiko-reviews; +Cc: bpf
On Tue, Jun 09, 2026 at 10:57:22AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [Medium] Missing strict zero-validation for the unused `path_fd` field when the `BPF_F_UPROBE_MULTI_PATH_FD` flag is not set.
> - [Low] Mixing scope-based cleanup (`CLASS()`) with `goto`-based error handling in `bpf_uprobe_multi_link_attach`.
> --
>
> commit f7958ff1ce57c1ab456d3f134881a0081a58b8ed
> Author: Jiri Olsa <jolsa@kernel.org>
>
> bpf: Add support to specify uprobe_multi target via file descriptor
>
> This commit adds the BPF_F_UPROBE_MULTI_PATH_FD flag to allow uprobe_multi
> links to specify the target binary using an already opened file descriptor
> instead of a path string.
>
> > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > index 970ce7bbf99e1..4965006d58ee6 100644
> > --- a/kernel/trace/bpf_trace.c
> > +++ b/kernel/trace/bpf_trace.c
> [ ... ]
> > @@ -3240,29 +3241,51 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
> [ ... ]
> > uref_ctr_offsets = u64_to_user_ptr(attr->link_create.uprobe_multi.ref_ctr_offsets);
> > ucookies = u64_to_user_ptr(attr->link_create.uprobe_multi.cookies);
> > + upath = u64_to_user_ptr(attr->link_create.uprobe_multi.path);
> >
> > - err = user_path_at(AT_FDCWD, upath, LOOKUP_FOLLOW, &path);
> > - if (err)
> > - return err;
> > + if (flags & BPF_F_UPROBE_MULTI_PATH_FD) {
> > + /*
> > + * When BPF_F_UPROBE_MULTI_PATH_FD is set, the executable is identified
> > + * by path_fd, and upath must be NULL.
> > + */
> > + if (upath)
> > + return -EINVAL;
> > +
> > + CLASS(fd, f)(attr->link_create.uprobe_multi.path_fd);
>
> [Severity: Low]
> Does this code violate the cleanup subsystem guidelines by mixing scope-based
> cleanup with goto-based error handling?
>
> The bpf_uprobe_multi_link_attach() function relies heavily on goto labels
> for error paths (e.g., error_path_put, error_free, error_unregister). The
> kernel guidelines state that goto-based cleanup and scope-based cleanup
> helpers (like CLASS) should never be mixed in the same function.
>
> Should this function be fully converted to scope-based cleanup, or should it
> use explicit fdget()/fdput() without CLASS() instead?
ah true, I'll unwind the fd retrieval or perhaps move the path retrival
into separate function, will check
> > + if (fd_empty(f))
> > + return -EBADF;
> > + path = fd_file(f)->f_path;
> > + path_get(&path);
> > + } else {
> > + /*
> > + * When BPF_F_UPROBE_MULTI_PATH_FD is not set, the path is resolved
> > + * relative to the cwd (AT_FDCWD) or absolute using the upath string.
> > + */
> > + if (!upath)
> > + return -EINVAL;
>
> [Severity: Medium]
> Should there be strict zero-validation for the unused path_fd field here?
>
> When the BPF_F_UPROBE_MULTI_PATH_FD flag is not set, this branch is taken
> and attr->link_create.uprobe_multi.path_fd is ignored without being
> validated as zero.
>
> If userspace passes uninitialized garbage in this field, it won't be
> rejected. Could this break forward compatibility if path_fd needs to be
> assigned a new meaning in the future?
right, I'll add the path_fd check in here
jirka
>
> > +
> > + err = user_path_at(AT_FDCWD, upath, LOOKUP_FOLLOW, &path);
> > + if (err)
> > + return err;
> > + }
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260609104244.588321-1-jolsa@kernel.org?part=2
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor
2026-06-09 10:42 ` [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor Jiri Olsa
2026-06-09 10:57 ` sashiko-bot
@ 2026-06-09 11:17 ` bot+bpf-ci
2026-06-09 13:24 ` Jiri Olsa
2026-06-09 18:22 ` Alexei Starovoitov
2 siblings, 1 reply; 12+ messages in thread
From: bot+bpf-ci @ 2026-06-09 11:17 UTC (permalink / raw)
To: jolsa, ast, daniel, andrii
Cc: bpf, martin.lau, eddyz87, songliubraving, yhs, oleg, mhiramat,
ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1646 bytes --]
> Allow uprobe_multi link to identify the target binary by an already
> opened file descriptor.
>
> Adding new BPF_F_UPROBE_MULTI_PATH_FD flag and the path_fd field for
> the attr.link_create.uprobe_multi struct.
>
> When the flag is set, we resolve the target from path_fd, without the
> flag, we keep the existing string path behavior.
>
> I don't see a use case for supporting O_PATH file descriptors, because
> we need need to read the binary first to get probes offsets, so I'm
> using the CLASS(fd, f), which fails for O_PATH fds.
>
> Assisted-by: Codex:GPT-5.4
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
This change also fixes a latent bug in bpf_link_show_fdinfo(), changing
the exact-equality test to a bitwise test:
else if (link->type == BPF_LINK_TYPE_UPROBE_MULTI)
seq_printf(m, "link_type:\t%s\n", link->flags & BPF_F_UPROBE_MULTI_RETURN ?
"uretprobe_multi" : "uprobe_multi");
The original "link->flags == BPF_F_UPROBE_MULTI_RETURN" was harmless
while BPF_F_UPROBE_MULTI_RETURN was the only defined uprobe_multi flag.
This commit adds a second flag (BPF_F_UPROBE_MULTI_PATH_FD), so the
exact "==" comparison would misreport a uretprobe_multi link as
"uprobe_multi" whenever both flags are set.
Should this carry a Fixes: tag pointing at the commit that introduced
the fragile comparison?
Fixes: 803f0700a3bb ("bpf: Show precise link_type for {uprobe,kprobe}_multi fdinfo")
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27201419867
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor
2026-06-09 11:17 ` bot+bpf-ci
@ 2026-06-09 13:24 ` Jiri Olsa
0 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 13:24 UTC (permalink / raw)
To: bot+bpf-ci
Cc: ast, daniel, andrii, bpf, martin.lau, eddyz87, songliubraving,
yhs, oleg, mhiramat, martin.lau, yonghong.song, clm,
ihor.solodrai
On Tue, Jun 09, 2026 at 11:17:11AM +0000, bot+bpf-ci@kernel.org wrote:
> > Allow uprobe_multi link to identify the target binary by an already
> > opened file descriptor.
> >
> > Adding new BPF_F_UPROBE_MULTI_PATH_FD flag and the path_fd field for
> > the attr.link_create.uprobe_multi struct.
> >
> > When the flag is set, we resolve the target from path_fd, without the
> > flag, we keep the existing string path behavior.
> >
> > I don't see a use case for supporting O_PATH file descriptors, because
> > we need need to read the binary first to get probes offsets, so I'm
> > using the CLASS(fd, f), which fails for O_PATH fds.
> >
> > Assisted-by: Codex:GPT-5.4
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
>
> This change also fixes a latent bug in bpf_link_show_fdinfo(), changing
> the exact-equality test to a bitwise test:
>
> else if (link->type == BPF_LINK_TYPE_UPROBE_MULTI)
> seq_printf(m, "link_type:\t%s\n", link->flags & BPF_F_UPROBE_MULTI_RETURN ?
> "uretprobe_multi" : "uprobe_multi");
>
> The original "link->flags == BPF_F_UPROBE_MULTI_RETURN" was harmless
> while BPF_F_UPROBE_MULTI_RETURN was the only defined uprobe_multi flag.
> This commit adds a second flag (BPF_F_UPROBE_MULTI_PATH_FD), so the
> exact "==" comparison would misreport a uretprobe_multi link as
> "uprobe_multi" whenever both flags are set.
>
> Should this carry a Fixes: tag pointing at the commit that introduced
> the fragile comparison?
>
> Fixes: 803f0700a3bb ("bpf: Show precise link_type for {uprobe,kprobe}_multi fdinfo")
hum, I don't think so, it wasn't really a bug until this change
jirka
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27201419867
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor
2026-06-09 10:42 ` [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor Jiri Olsa
2026-06-09 10:57 ` sashiko-bot
2026-06-09 11:17 ` bot+bpf-ci
@ 2026-06-09 18:22 ` Alexei Starovoitov
2 siblings, 0 replies; 12+ messages in thread
From: Alexei Starovoitov @ 2026-06-09 18:22 UTC (permalink / raw)
To: Jiri Olsa, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Oleg Nesterov, Masami Hiramatsu
On Tue Jun 9, 2026 at 3:42 AM PDT, Jiri Olsa wrote:
> flags = attr->link_create.uprobe_multi.flags;
> - if (flags & ~BPF_F_UPROBE_MULTI_RETURN)
> + if (flags & ~(BPF_F_UPROBE_MULTI_RETURN|BPF_F_UPROBE_MULTI_PATH_FD))
In addition to what bots said, pls run checkpatch on above.
It should complain of lack of ' '.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH bpf-next 3/6] libbpf: Add path_fd to struct bpf_link_create_opts
2026-06-09 10:42 [PATCH bpf-next 0/6] bpf: Allow uprobe_multi binary specified by file descriptor Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 1/6] bpf: Use user_path_at for path resolution in uprobe_multi Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 2/6] bpf: Add support to specify uprobe_multi target via file descriptor Jiri Olsa
@ 2026-06-09 10:42 ` Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 4/6] selftests/bpf: Add uprobe_multi path_fd test Jiri Olsa
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 10:42 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Oleg Nesterov, Masami Hiramatsu
Adding the path_fd field to struct bpf_link_create_opts and passing it
through kernel attr interface.
Assisted-by: Codex:GPT-5.4
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/lib/bpf/bpf.c | 1 +
tools/lib/bpf/bpf.h | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index f37e3416f61a..96819c082c77 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -842,6 +842,7 @@ int bpf_link_create(int prog_fd, int target_fd,
attr.link_create.uprobe_multi.ref_ctr_offsets = ptr_to_u64(OPTS_GET(opts, uprobe_multi.ref_ctr_offsets, 0));
attr.link_create.uprobe_multi.cookies = ptr_to_u64(OPTS_GET(opts, uprobe_multi.cookies, 0));
attr.link_create.uprobe_multi.pid = OPTS_GET(opts, uprobe_multi.pid, 0);
+ attr.link_create.uprobe_multi.path_fd = OPTS_GET(opts, uprobe_multi.path_fd, 0);
if (!OPTS_ZEROED(opts, uprobe_multi))
return libbpf_err(-EINVAL);
break;
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 012354131cf6..7534a593edae 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -444,6 +444,7 @@ struct bpf_link_create_opts {
const unsigned long *ref_ctr_offsets;
const __u64 *cookies;
__u32 pid;
+ __u32 path_fd;
} uprobe_multi;
struct {
__u64 cookie;
@@ -477,7 +478,7 @@ struct bpf_link_create_opts {
};
size_t :0;
};
-#define bpf_link_create_opts__last_field uprobe_multi.pid
+#define bpf_link_create_opts__last_field uprobe_multi.path_fd
LIBBPF_API int bpf_link_create(int prog_fd, int target_fd,
enum bpf_attach_type attach_type,
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH bpf-next 4/6] selftests/bpf: Add uprobe_multi path_fd test
2026-06-09 10:42 [PATCH bpf-next 0/6] bpf: Allow uprobe_multi binary specified by file descriptor Jiri Olsa
` (2 preceding siblings ...)
2026-06-09 10:42 ` [PATCH bpf-next 3/6] libbpf: Add path_fd to struct bpf_link_create_opts Jiri Olsa
@ 2026-06-09 10:42 ` Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 5/6] selftests/bpf: Add uprobe_multi path_fd fail tests Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 6/6] selftests/bpf: Fix typo in verify_umulti_link_info Jiri Olsa
5 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 10:42 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Oleg Nesterov, Masami Hiramatsu
Add a uprobe_multi link API selftest that opens /proc/self/exe and passes
the resulting descriptor through opts.uprobe_multi.path_fd with
BPF_F_UPROBE_MULTI_PATH_FD set.
Assisted-by: Codex:GPT-5.4
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
.../bpf/prog_tests/uprobe_multi_test.c | 62 +++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
index 56cbea280fbd..8c9eba1d4084 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
@@ -2,6 +2,7 @@
#include <unistd.h>
#include <pthread.h>
+#include <fcntl.h>
#include <test_progs.h>
#include "uprobe_multi.skel.h"
#include "uprobe_multi_bench.skel.h"
@@ -757,6 +758,65 @@ static void test_link_api(void)
__test_link_api(&child);
}
+static void test_link_api_path_fd(void)
+{
+ const char *resolve_path = "/proc/self/exe";
+ LIBBPF_OPTS(bpf_link_create_opts, opts);
+ int prog_fd, link_fd = -1, path_fd = -1;
+ struct uprobe_multi *skel = NULL;
+ unsigned long *offsets = NULL;
+ const char *syms[3] = {
+ "uprobe_multi_func_1",
+ "uprobe_multi_func_2",
+ "uprobe_multi_func_3",
+ };
+ int err;
+
+ err = elf_resolve_syms_offsets(resolve_path, ARRAY_SIZE(syms), syms,
+ &offsets, STT_FUNC);
+ if (!ASSERT_OK(err, "elf_resolve_syms_offsets"))
+ return;
+
+ path_fd = open(resolve_path, O_RDONLY);
+ if (!ASSERT_GE(path_fd, 0, "path_fd"))
+ goto cleanup;
+
+ opts.uprobe_multi.path_fd = path_fd;
+ opts.uprobe_multi.offsets = offsets;
+ opts.uprobe_multi.cnt = ARRAY_SIZE(syms);
+ opts.uprobe_multi.flags = BPF_F_UPROBE_MULTI_PATH_FD;
+
+ skel = uprobe_multi__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "uprobe_multi__open_and_load"))
+ goto cleanup;
+
+ prog_fd = bpf_program__fd(skel->progs.uprobe);
+ link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &opts);
+ if (!ASSERT_GE(link_fd, 0, "bpf_link_create"))
+ goto cleanup;
+
+ skel->bss->uprobe_multi_func_1_addr = (__u64)uprobe_multi_func_1;
+ skel->bss->uprobe_multi_func_2_addr = (__u64)uprobe_multi_func_2;
+ skel->bss->uprobe_multi_func_3_addr = (__u64)uprobe_multi_func_3;
+ skel->bss->pid = getpid();
+
+ uprobe_multi_func_1();
+ uprobe_multi_func_2();
+ uprobe_multi_func_3();
+
+ ASSERT_EQ(skel->bss->uprobe_multi_func_1_result, 1, "uprobe_multi_func_1_result");
+ ASSERT_EQ(skel->bss->uprobe_multi_func_2_result, 1, "uprobe_multi_func_2_result");
+ ASSERT_EQ(skel->bss->uprobe_multi_func_3_result, 1, "uprobe_multi_func_3_result");
+
+cleanup:
+ if (link_fd >= 0)
+ close(link_fd);
+ if (path_fd >= 0)
+ close(path_fd);
+ uprobe_multi__destroy(skel);
+ free(offsets);
+}
+
static struct bpf_program *
get_program(struct uprobe_multi_consumers *skel, int prog)
{
@@ -1354,6 +1414,8 @@ void test_uprobe_multi_test(void)
test_attach_api_syms();
if (test__start_subtest("link_api"))
test_link_api();
+ if (test__start_subtest("link_api_path_fd"))
+ test_link_api_path_fd();
if (test__start_subtest("bench_uprobe"))
test_bench_attach_uprobe();
if (test__start_subtest("bench_usdt"))
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH bpf-next 5/6] selftests/bpf: Add uprobe_multi path_fd fail tests
2026-06-09 10:42 [PATCH bpf-next 0/6] bpf: Allow uprobe_multi binary specified by file descriptor Jiri Olsa
` (3 preceding siblings ...)
2026-06-09 10:42 ` [PATCH bpf-next 4/6] selftests/bpf: Add uprobe_multi path_fd test Jiri Olsa
@ 2026-06-09 10:42 ` Jiri Olsa
2026-06-09 10:42 ` [PATCH bpf-next 6/6] selftests/bpf: Fix typo in verify_umulti_link_info Jiri Olsa
5 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 10:42 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Oleg Nesterov, Masami Hiramatsu
Adding tests to attach_api_fails suite to make sure we fail
wrong setup for path_fd usage.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
.../bpf/prog_tests/uprobe_multi_test.c | 32 ++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
index 8c9eba1d4084..71eea809dce3 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
@@ -537,7 +537,37 @@ static void test_attach_api_fails(void)
link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &opts);
if (!ASSERT_ERR(link_fd, "link_fd"))
goto cleanup;
- ASSERT_EQ(link_fd, -EINVAL, "pid_is_wrong");
+ if (!ASSERT_EQ(link_fd, -EINVAL, "pid_is_wrong"))
+ goto cleanup;
+
+ /* wrong path_fd */
+ LIBBPF_OPTS_RESET(opts,
+ .uprobe_multi.path = NULL,
+ .uprobe_multi.path_fd = -1,
+ .uprobe_multi.flags = BPF_F_UPROBE_MULTI_PATH_FD,
+ .uprobe_multi.offsets = (unsigned long *) &offset,
+ .uprobe_multi.cnt = 1,
+ );
+
+ link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &opts);
+ if (!ASSERT_ERR(link_fd, "link_fd"))
+ goto cleanup;
+ if (!ASSERT_EQ(link_fd, -EBADF, "path_fd_is_wrong"))
+ goto cleanup;
+
+ /* path and path_fd both set with BPF_F_UPROBE_MULTI_PATH_FD flag */
+ LIBBPF_OPTS_RESET(opts,
+ .uprobe_multi.path = path,
+ .uprobe_multi.path_fd = 1,
+ .uprobe_multi.flags = BPF_F_UPROBE_MULTI_PATH_FD,
+ .uprobe_multi.offsets = (unsigned long *) &offset,
+ .uprobe_multi.cnt = 1,
+ );
+
+ link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &opts);
+ if (!ASSERT_ERR(link_fd, "link_fd"))
+ goto cleanup;
+ ASSERT_EQ(link_fd, -EINVAL, "path_and_path_fd_together");
cleanup:
if (link_fd >= 0)
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH bpf-next 6/6] selftests/bpf: Fix typo in verify_umulti_link_info
2026-06-09 10:42 [PATCH bpf-next 0/6] bpf: Allow uprobe_multi binary specified by file descriptor Jiri Olsa
` (4 preceding siblings ...)
2026-06-09 10:42 ` [PATCH bpf-next 5/6] selftests/bpf: Add uprobe_multi path_fd fail tests Jiri Olsa
@ 2026-06-09 10:42 ` Jiri Olsa
5 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2026-06-09 10:42 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Oleg Nesterov, Masami Hiramatsu
We verify info.uprobe_multi.flags against wrong kprobe-multi flag
(BPF_F_KPROBE_MULTI_RETURN). It's the same value as the correct
flag (BPF_F_UPROBE_MULTI_RETURN), so there's not functional change.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/testing/selftests/bpf/prog_tests/fill_link_info.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c
index e40114620751..f589eefbf9fb 100644
--- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c
+++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c
@@ -469,7 +469,7 @@ verify_umulti_link_info(int fd, bool retprobe, __u64 *offsets,
ASSERT_EQ(info.uprobe_multi.pid, getpid(), "info.uprobe_multi.pid");
ASSERT_EQ(info.uprobe_multi.count, 3, "info.uprobe_multi.count");
- ASSERT_EQ(info.uprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN,
+ ASSERT_EQ(info.uprobe_multi.flags & BPF_F_UPROBE_MULTI_RETURN,
retprobe, "info.uprobe_multi.flags.retprobe");
ASSERT_EQ(info.uprobe_multi.path_size, strlen(path) + 1, "info.uprobe_multi.path_size");
ASSERT_STREQ(path_buf, path, "info.uprobe_multi.path");
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread