This patchset enhances the usability of kprobe_multi programs by introducing
support for ->fill_link_info. This allows users to easily determine the
probed functions associated with a kprobe_multi program. While
`bpftool perf show` already provides information about functions probed by
perf_event programs, supporting ->fill_link_info ensures consistent access to
this information across all bpf links.
In addition, this patch extends support to generic perf events, which are
currently not covered by `bpftool perf show`. While userspace is exposed to
only the perf type and config, other attributes such as sample_period and
sample_freq are disregarded.
To ensure accurate identification of probed functions, it is preferable to
expose the address directly rather than relying solely on the symbol name.
However, this implementation respects the kptr_restrict setting and avoids
exposing the address if it is not permitted.
v2->v3:
- Expose flags instead of retporbe (Andrii)
- Simplify the check on kmulti_link->cnt (Andrii)
- Use kallsyms_show_value() instead (Andrii)
- Show also the module name for kprobe_multi (Andrii)
- Add new enum bpf_perf_link_type (Andrii)
- Move perf event names into bpftool (Andrii, Quentin, Jiri)
- Keep perf event names in sync with perf tools (Jiri)
v1->v2:
- Fix sparse warning (Stanislav, lkp@intel.com)
- Fix BPF CI build error
- Reuse kernel_syms_load() (Alexei)
- Print 'name' instead of 'func' (Alexei)
- Show whether the probe is retprobe or not (Andrii)
- Add comment for the meaning of perf_event name (Andrii)
- Add support for generic perf event
- Adhere to the kptr_restrict setting
RFC->v1:
- Use a single copy_to_user() instead (Jiri)
- Show also the symbol name in bpftool (Quentin, Alexei)
- Use calloc() instead of malloc() in bpftool (Quentin)
- Avoid having conditional entries in the JSON output (Quentin)
- Drop ->show_fdinfo (Alexei)
- Use __u64 instead of __aligned_u64 for the field addr (Alexei)
- Avoid the contradiction in perf_event name length (Alexei)
- Address a build warning reported by kernel test robot [off-list ref]
Yafang Shao (10):
bpf: Support ->fill_link_info for kprobe_multi
bpftool: Dump the kernel symbol's module name
bpftool: Show probed function in kprobe_multi link info
bpf: Protect probed address based on kptr_restrict setting
bpf: Clear the probe_addr for uprobe
bpf: Expose symbol's respective address
bpf: Add a common helper bpf_copy_to_user()
bpf: Support ->fill_link_info for perf_event
bpftool: Add perf event names
bpftool: Show probed function in perf_event link info
include/uapi/linux/bpf.h | 37 +++++
kernel/bpf/syscall.c | 158 +++++++++++++++++--
kernel/trace/bpf_trace.c | 32 +++-
kernel/trace/trace_kprobe.c | 7 +-
tools/bpf/bpftool/link.c | 322 +++++++++++++++++++++++++++++++++++++-
tools/bpf/bpftool/perf.c | 107 +++++++++++++
tools/bpf/bpftool/perf.h | 11 ++
tools/bpf/bpftool/xlated_dumper.c | 6 +-
tools/bpf/bpftool/xlated_dumper.h | 2 +
tools/include/uapi/linux/bpf.h | 37 +++++
10 files changed, 700 insertions(+), 19 deletions(-)
create mode 100644 tools/bpf/bpftool/perf.h
--
1.8.3.1
With the addition of support for fill_link_info to the kprobe_multi link,
users will gain the ability to inspect it conveniently using the
`bpftool link show`. This enhancement provides valuable information to the
user, including the count of probed functions and their respective
addresses. It's important to note that if the kptr_restrict setting is not
permitted, the probed address will not be exposed, ensuring security.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 5 +++++
kernel/trace/bpf_trace.c | 28 ++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 5 +++++
3 files changed, 38 insertions(+)
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
quoted hunk
With the addition of support for fill_link_info to the kprobe_multi link,
users will gain the ability to inspect it conveniently using the
`bpftool link show`. This enhancement provides valuable information to the
user, including the count of probed functions and their respective
addresses. It's important to note that if the kptr_restrict setting is not
permitted, the probed address will not be exposed, ensuring security.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 5 +++++
kernel/trace/bpf_trace.c | 28 ++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 5 +++++
3 files changed, 38 insertions(+)
besides what Jiri said, flags should always be returned, just like
cnt. So structure code instead around uaddrs being optional, that will
everything more straightforward (i.e., fill out everything but uaddrs
and then at the end fill out addrs if uaddrs is not zero)
On Sat, Jun 17, 2023 at 1:24 AM Andrii Nakryiko
[off-list ref] wrote:
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
quoted
With the addition of support for fill_link_info to the kprobe_multi link,
users will gain the ability to inspect it conveniently using the
`bpftool link show`. This enhancement provides valuable information to the
user, including the count of probed functions and their respective
addresses. It's important to note that if the kptr_restrict setting is not
permitted, the probed address will not be exposed, ensuring security.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 5 +++++
kernel/trace/bpf_trace.c | 28 ++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 5 +++++
3 files changed, 38 insertions(+)
besides what Jiri said, flags should always be returned, just like
cnt. So structure code instead around uaddrs being optional, that will
everything more straightforward (i.e., fill out everything but uaddrs
and then at the end fill out addrs if uaddrs is not zero)
Agree. That will be more straightforward. Will change it.
--
Regards
Yafang
If the kernel symbol is in a module, we will dump the module name as
well.
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/xlated_dumper.c | 6 +++++-
tools/bpf/bpftool/xlated_dumper.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
If the kernel symbol is in a module, we will dump the module name as
well.
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/xlated_dumper.c | 6 +++++-
tools/bpf/bpftool/xlated_dumper.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
Nit: MODULE_MAX_NAME would be more consistent and would make more sense
to me? And it would avoid confusion with MODULE_NAME_LEN from kernel,
which doesn't have the same value.
If the kernel symbol is in a module, we will dump the module name as
well.
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/xlated_dumper.c | 6 +++++-
tools/bpf/bpftool/xlated_dumper.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
Nit: MODULE_MAX_NAME would be more consistent and would make more sense
to me? And it would avoid confusion with MODULE_NAME_LEN from kernel,
which doesn't have the same value.
Will use MODULE_MAX_NAME instead.
--
Regards
Yafang
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
quoted hunk
If the kernel symbol is in a module, we will dump the module name as
well.
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/xlated_dumper.c | 6 +++++-
tools/bpf/bpftool/xlated_dumper.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
On Sat, Jun 17, 2023 at 1:25 AM Andrii Nakryiko
[off-list ref] wrote:
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
quoted
If the kernel symbol is in a module, we will dump the module name as
well.
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/xlated_dumper.c | 6 +++++-
tools/bpf/bpftool/xlated_dumper.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
@@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)returnerr;}+staticintcmp_u64(constvoid*A,constvoid*B)+{+const__u64*a=A,*b=B;++return*a-*b;+}++staticvoid+show_kprobe_multi_json(structbpf_link_info*info,json_writer_t*wtr)+{+__u32i,j=0;+__u64*addrs;++jsonw_uint_field(json_wtr,"retprobe",+info->kprobe_multi.flags&BPF_F_KPROBE_MULTI_RETURN);+jsonw_uint_field(json_wtr,"func_cnt",info->kprobe_multi.count);+jsonw_name(json_wtr,"funcs");+jsonw_start_array(json_wtr);+addrs=(__u64*)u64_to_ptr(info->kprobe_multi.addrs);+qsort((void*)addrs,info->kprobe_multi.count,sizeof(__u64),cmp_u64);++/* Load it once for all. */+if(!dd.sym_count)+kernel_syms_load(&dd);+for(i=0;i<dd.sym_count;i++){+if(dd.sym_mapping[i].address!=addrs[j])+continue;+jsonw_start_object(json_wtr);+jsonw_uint_field(json_wtr,"addr",dd.sym_mapping[i].address);+jsonw_string_field(json_wtr,"func",dd.sym_mapping[i].name);+/* Print none if it is vmlinux */+jsonw_string_field(json_wtr,"module",dd.sym_mapping[i].module);+jsonw_end_object(json_wtr);+if(j++==info->kprobe_multi.count)+break;+}+jsonw_end_array(json_wtr);+}+staticintshow_link_close_json(intfd,structbpf_link_info*info){structbpf_prog_infoprog_info;
The "retprobe" field could maybe be a boolean rather than an int.
+ jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
+ jsonw_name(json_wtr, "funcs");
+ jsonw_start_array(json_wtr);
+ addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
+ qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
+
+ /* Load it once for all. */
+ if (!dd.sym_count)
+ kernel_syms_load(&dd);
+ for (i = 0; i < dd.sym_count; i++) {
+ if (dd.sym_mapping[i].address != addrs[j])
+ continue;
+ jsonw_start_object(json_wtr);
+ jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
+ jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
+ /* Print none if it is vmlinux */
+ jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
Can we trim the square brackets around module names for the JSON output,
please? They make entries look like arrays; but mostly, if we keep them,
we're forcing every consumer to trim them on their side before being
able to reuse the value.
The "retprobe" field could maybe be a boolean rather than an int.
Will change it.
quoted
+ jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
+ jsonw_name(json_wtr, "funcs");
+ jsonw_start_array(json_wtr);
+ addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
+ qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
+
+ /* Load it once for all. */
+ if (!dd.sym_count)
+ kernel_syms_load(&dd);
+ for (i = 0; i < dd.sym_count; i++) {
+ if (dd.sym_mapping[i].address != addrs[j])
+ continue;
+ jsonw_start_object(json_wtr);
+ jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
+ jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
+ /* Print none if it is vmlinux */
+ jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
Can we trim the square brackets around module names for the JSON output,
please? They make entries look like arrays; but mostly, if we keep them,
we're forcing every consumer to trim them on their side before being
able to reuse the value.
@@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)returnerr;}+staticintcmp_u64(constvoid*A,constvoid*B)+{+const__u64*a=A,*b=B;++return*a-*b;+}++staticvoid+show_kprobe_multi_json(structbpf_link_info*info,json_writer_t*wtr)+{+__u32i,j=0;+__u64*addrs;++jsonw_uint_field(json_wtr,"retprobe",+info->kprobe_multi.flags&BPF_F_KPROBE_MULTI_RETURN);+jsonw_uint_field(json_wtr,"func_cnt",info->kprobe_multi.count);+jsonw_name(json_wtr,"funcs");+jsonw_start_array(json_wtr);+addrs=(__u64*)u64_to_ptr(info->kprobe_multi.addrs);+qsort((void*)addrs,info->kprobe_multi.count,sizeof(__u64),cmp_u64);++/* Load it once for all. */+if(!dd.sym_count)+kernel_syms_load(&dd);+for(i=0;i<dd.sym_count;i++){+if(dd.sym_mapping[i].address!=addrs[j])+continue;+jsonw_start_object(json_wtr);+jsonw_uint_field(json_wtr,"addr",dd.sym_mapping[i].address);+jsonw_string_field(json_wtr,"func",dd.sym_mapping[i].name);+/* Print none if it is vmlinux */+jsonw_string_field(json_wtr,"module",dd.sym_mapping[i].module);+jsonw_end_object(json_wtr);+if(j++==info->kprobe_multi.count)+break;+}+jsonw_end_array(json_wtr);+}+staticintshow_link_close_json(intfd,structbpf_link_info*info){structbpf_prog_infoprog_info;
@@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)returnerr;}+staticintcmp_u64(constvoid*A,constvoid*B)+{+const__u64*a=A,*b=B;++return*a-*b;+}++staticvoid+show_kprobe_multi_json(structbpf_link_info*info,json_writer_t*wtr)+{+__u32i,j=0;+__u64*addrs;++jsonw_uint_field(json_wtr,"retprobe",+info->kprobe_multi.flags&BPF_F_KPROBE_MULTI_RETURN);+jsonw_uint_field(json_wtr,"func_cnt",info->kprobe_multi.count);+jsonw_name(json_wtr,"funcs");+jsonw_start_array(json_wtr);+addrs=(__u64*)u64_to_ptr(info->kprobe_multi.addrs);+qsort((void*)addrs,info->kprobe_multi.count,sizeof(__u64),cmp_u64);++/* Load it once for all. */+if(!dd.sym_count)+kernel_syms_load(&dd);+for(i=0;i<dd.sym_count;i++){+if(dd.sym_mapping[i].address!=addrs[j])+continue;+jsonw_start_object(json_wtr);+jsonw_uint_field(json_wtr,"addr",dd.sym_mapping[i].address);+jsonw_string_field(json_wtr,"func",dd.sym_mapping[i].name);+/* Print none if it is vmlinux */+jsonw_string_field(json_wtr,"module",dd.sym_mapping[i].module);+jsonw_end_object(json_wtr);+if(j++==info->kprobe_multi.count)+break;+}+jsonw_end_array(json_wtr);+}+staticintshow_link_close_json(intfd,structbpf_link_info*info){structbpf_prog_infoprog_info;
@@ -351,6 +395,44 @@ void netfilter_dump_plain(const struct bpf_link_info *info)printf(" flags 0x%x",info->netfilter.flags);}+staticvoidshow_kprobe_multi_plain(structbpf_link_info*info)+{+__u32i,j=0;+__u64*addrs;++if(!info->kprobe_multi.count)+return;++printf("\n\tretprobe %d func_cnt %u ",+info->kprobe_multi.flags&BPF_F_KPROBE_MULTI_RETURN,+info->kprobe_multi.count);+addrs=(__u64*)u64_to_ptr(info->kprobe_multi.addrs);+qsort((void*)addrs,info->kprobe_multi.count,sizeof(__u64),cmp_u64);++/* Load it once for all. */+if(!dd.sym_count)+kernel_syms_load(&dd);+for(i=0;i<dd.sym_count;i++){+if(dd.sym_mapping[i].address!=addrs[j])+continue;+if(!j)+printf("\n\taddrs %016lx funcs %s",+dd.sym_mapping[i].address,+dd.sym_mapping[i].name);+else+printf("\n\t %016lx %s",+dd.sym_mapping[i].address,+dd.sym_mapping[i].name);+if(dd.sym_mapping[i].module[0]!='\0')+printf(" %s ",dd.sym_mapping[i].module);+else+printf(" ");
Could you explain what these extra spaces after module names are for?
There are two spaces. We use two spaces to seperate different items
printed in bpftool. For example,
"4: kprobe_multi prog 16"
There are two spaces between the "type" and the "prog".
We always print these two spaces after one item is printed:
printf("type %u ", info->type);
printf("prog %u ", info->prog_id);
That way, we can add new item easily and consistently.
--
Regards
Yafang
@@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)returnerr;}+staticintcmp_u64(constvoid*A,constvoid*B)+{+const__u64*a=A,*b=B;++return*a-*b;+}++staticvoid+show_kprobe_multi_json(structbpf_link_info*info,json_writer_t*wtr)+{+__u32i,j=0;+__u64*addrs;++jsonw_uint_field(json_wtr,"retprobe",+info->kprobe_multi.flags&BPF_F_KPROBE_MULTI_RETURN);+jsonw_uint_field(json_wtr,"func_cnt",info->kprobe_multi.count);+jsonw_name(json_wtr,"funcs");+jsonw_start_array(json_wtr);+addrs=(__u64*)u64_to_ptr(info->kprobe_multi.addrs);+qsort((void*)addrs,info->kprobe_multi.count,sizeof(__u64),cmp_u64);++/* Load it once for all. */+if(!dd.sym_count)+kernel_syms_load(&dd);+for(i=0;i<dd.sym_count;i++){+if(dd.sym_mapping[i].address!=addrs[j])+continue;+jsonw_start_object(json_wtr);+jsonw_uint_field(json_wtr,"addr",dd.sym_mapping[i].address);+jsonw_string_field(json_wtr,"func",dd.sym_mapping[i].name);+/* Print none if it is vmlinux */+jsonw_string_field(json_wtr,"module",dd.sym_mapping[i].module);+jsonw_end_object(json_wtr);+if(j++==info->kprobe_multi.count)+break;+}+jsonw_end_array(json_wtr);+}+staticintshow_link_close_json(intfd,structbpf_link_info*info){structbpf_prog_infoprog_info;
@@ -351,6 +395,44 @@ void netfilter_dump_plain(const struct bpf_link_info *info)printf(" flags 0x%x",info->netfilter.flags);}+staticvoidshow_kprobe_multi_plain(structbpf_link_info*info)+{+__u32i,j=0;+__u64*addrs;++if(!info->kprobe_multi.count)+return;++printf("\n\tretprobe %d func_cnt %u ",+info->kprobe_multi.flags&BPF_F_KPROBE_MULTI_RETURN,+info->kprobe_multi.count);+addrs=(__u64*)u64_to_ptr(info->kprobe_multi.addrs);+qsort((void*)addrs,info->kprobe_multi.count,sizeof(__u64),cmp_u64);++/* Load it once for all. */+if(!dd.sym_count)+kernel_syms_load(&dd);+for(i=0;i<dd.sym_count;i++){+if(dd.sym_mapping[i].address!=addrs[j])+continue;+if(!j)+printf("\n\taddrs %016lx funcs %s",+dd.sym_mapping[i].address,+dd.sym_mapping[i].name);+else+printf("\n\t %016lx %s",+dd.sym_mapping[i].address,+dd.sym_mapping[i].name);+if(dd.sym_mapping[i].module[0]!='\0')+printf(" %s ",dd.sym_mapping[i].module);+else+printf(" ");
Could you explain what these extra spaces after module names are for?
There are two spaces. We use two spaces to seperate different items
printed in bpftool. For example,
"4: kprobe_multi prog 16"
There are two spaces between the "type" and the "prog".
We always print these two spaces after one item is printed:
printf("type %u ", info->type);
printf("prog %u ", info->prog_id);
That way, we can add new item easily and consistently.
I'm not sure we _always_ do it at the end of lines, but it seems to be
rather consistent in link.c at least. For my part I don't know if this
printf(" ") is really necessary - I'd rather avoid spaces at the end of
lines, but then there would be several other locations to update. So I
don't have any objection, either.
Quentin
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
Show the already expose kprobe_multi link info in bpftool. The result as
follows,
52: kprobe_multi prog 381
retprobe 0 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
pids kprobe_multi(559862)
53: kprobe_multi prog 381
retprobe 1 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
it all subjective, but this format is a bit weird where "addrs" and
"funcs" is in first row to the left. Just makes everything wider. Why
not something like
addr func
ffffffff9ec44f20 schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
Not it's singular (addr and func) because it's column names,
basically. Can also do "addr func [module]".
On Sat, Jun 17, 2023 at 1:30 AM Andrii Nakryiko
[off-list ref] wrote:
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
quoted
Show the already expose kprobe_multi link info in bpftool. The result as
follows,
52: kprobe_multi prog 381
retprobe 0 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
pids kprobe_multi(559862)
53: kprobe_multi prog 381
retprobe 1 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
it all subjective, but this format is a bit weird where "addrs" and
"funcs" is in first row to the left. Just makes everything wider. Why
not something like
addr func
ffffffff9ec44f20 schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
It may be a little strange if there's only one function, but I don't
mind doing it as you suggested.
Not it's singular (addr and func) because it's column names,
basically. Can also do "addr func [module]".
The length of the function name is variable, so it is not easy to
determine where to put the "[module]". So I prefer to not show the
"[module]".
--
Regards
Yafang
On Fri, Jun 16, 2023 at 8:09 PM Yafang Shao [off-list ref] wrote:
On Sat, Jun 17, 2023 at 1:30 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
quoted
Show the already expose kprobe_multi link info in bpftool. The result as
follows,
52: kprobe_multi prog 381
retprobe 0 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
pids kprobe_multi(559862)
53: kprobe_multi prog 381
retprobe 1 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
it all subjective, but this format is a bit weird where "addrs" and
"funcs" is in first row to the left. Just makes everything wider. Why
not something like
addr func
ffffffff9ec44f20 schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
It may be a little strange if there's only one function, but I don't
mind doing it as you suggested.
quoted
Not it's singular (addr and func) because it's column names,
basically. Can also do "addr func [module]".
The length of the function name is variable, so it is not easy to
determine where to put the "[module]". So I prefer to not show the
"[module]".
"func [module]" in the header will give a hint of what is that value
in square brackets. I didn't mean to align it into a third column
On Wed, Jun 21, 2023 at 1:17 AM Andrii Nakryiko
[off-list ref] wrote:
On Fri, Jun 16, 2023 at 8:09 PM Yafang Shao [off-list ref] wrote:
quoted
On Sat, Jun 17, 2023 at 1:30 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao [off-list ref] wrote:
quoted
Show the already expose kprobe_multi link info in bpftool. The result as
follows,
52: kprobe_multi prog 381
retprobe 0 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
pids kprobe_multi(559862)
53: kprobe_multi prog 381
retprobe 1 func_cnt 7
addrs ffffffff9ec44f20 funcs schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffff9ec44fa0 schedule_timeout_uninterruptible
ffffffff9ec44fe0 schedule_timeout_idle
ffffffffc09468d0 xfs_trans_get_efd [xfs]
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
it all subjective, but this format is a bit weird where "addrs" and
"funcs" is in first row to the left. Just makes everything wider. Why
not something like
addr func
ffffffff9ec44f20 schedule_timeout_interruptible
ffffffff9ec44f60 schedule_timeout_killable
ffffffffc0953a10 xfs_trans_get_buf_map [xfs]
ffffffffc0957320 xfs_trans_get_dqtrx [xfs]
It may be a little strange if there's only one function, but I don't
mind doing it as you suggested.
quoted
Not it's singular (addr and func) because it's column names,
basically. Can also do "addr func [module]".
The length of the function name is variable, so it is not easy to
determine where to put the "[module]". So I prefer to not show the
"[module]".
"func [module]" in the header will give a hint of what is that value
in square brackets. I didn't mean to align it into a third column
Thanks for the clarification. Will change it.
--
Regards
Yafang
The probed address can be accessed by userspace through querying the task
file descriptor (fd). However, it is crucial to adhere to the kptr_restrict
setting and refrain from exposing the address if it is not permitted.
Signed-off-by: Yafang Shao <redacted>
---
kernel/trace/trace_kprobe.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
To avoid returning uninitialized or random values when querying the file
descriptor (fd) and accessing probe_addr, it is necessary to clear the
variable prior to its use.
Fixes: 41bdc4b40ed6 ("bpf: introduce bpf subcommand BPF_TASK_FD_QUERY")
Signed-off-by: Yafang Shao <redacted>
Cc: Yonghong Song <redacted>
---
kernel/trace/bpf_trace.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
From: Yonghong Song <hidden> Date: 2023-06-12 17:23:17
On 6/12/23 8:16 AM, Yafang Shao wrote:
To avoid returning uninitialized or random values when querying the file
descriptor (fd) and accessing probe_addr, it is necessary to clear the
variable prior to its use.
Fixes: 41bdc4b40ed6 ("bpf: introduce bpf subcommand BPF_TASK_FD_QUERY")
Signed-off-by: Yafang Shao <redacted>
Cc: Yonghong Song <redacted>
Thanks for the fix! LGTM.
Acked-by: Yonghong Song <redacted>
Since different symbols can share the same name, it is insufficient to only
expose the symbol name. It is essential to also expose the symbol address
so that users can accurately identify which one is being probed.
Signed-off-by: Yafang Shao <redacted>
---
kernel/trace/trace_kprobe.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
Add a common helper bpf_copy_to_user(), which will be used at multiple
places.
No functional change.
Signed-off-by: Yafang Shao <redacted>
---
kernel/bpf/syscall.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
By introducing support for ->fill_link_info to the perf_event link, users
gain the ability to inspect it using `bpftool link show`. While the current
approach involves accessing this information via `bpftool perf show`,
consolidating link information for all link types in one place offers
greater convenience. Additionally, this patch extends support to the
generic perf event, which is not currently accommodated by
`bpftool perf show`. While only the perf type and config are exposed to
userspace, other attributes such as sample_period and sample_freq are
ignored. It's important to note that if kptr_restrict is not permitted, the
probed address will not be exposed, maintaining security measures.
A new enum bpf_link_perf_event_type is introduced to help the user
understand which struct is relevant.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 32 +++++++++++
kernel/bpf/syscall.c | 124 +++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 32 +++++++++++
3 files changed, 188 insertions(+)
From: Yonghong Song <hidden> Date: 2023-06-12 17:37:39
On 6/12/23 8:16 AM, Yafang Shao wrote:
quoted hunk
By introducing support for ->fill_link_info to the perf_event link, users
gain the ability to inspect it using `bpftool link show`. While the current
approach involves accessing this information via `bpftool perf show`,
consolidating link information for all link types in one place offers
greater convenience. Additionally, this patch extends support to the
generic perf event, which is not currently accommodated by
`bpftool perf show`. While only the perf type and config are exposed to
userspace, other attributes such as sample_period and sample_freq are
ignored. It's important to note that if kptr_restrict is not permitted, the
probed address will not be exposed, maintaining security measures.
A new enum bpf_link_perf_event_type is introduced to help the user
understand which struct is relevant.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 32 +++++++++++
kernel/bpf/syscall.c | 124 +++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 32 +++++++++++
3 files changed, 188 insertions(+)
@@ -1056,6 +1056,16 @@ enum bpf_link_type {MAX_BPF_LINK_TYPE,};+enumbpf_perf_link_type{+BPF_PERF_LINK_UNSPEC=0,+BPF_PERF_LINK_UPROBE=1,+BPF_PERF_LINK_KPROBE=2,+BPF_PERF_LINK_TRACEPOINT=3,+BPF_PERF_LINK_PERF_EVENT=4,++MAX_BPF_LINK_PERF_EVENT_TYPE,+};+/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command**NONE(default):Nofurtherbpfprogramsallowedinthesubtree.
@@ -6443,7 +6453,29 @@ struct bpf_link_info {__u32count;__u32flags;}kprobe_multi;+struct{+__u64config;+__u32type;+}perf_event;/* BPF_LINK_PERF_EVENT_PERF_EVENT */+struct{+__aligned_u64file_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u32flags;+}uprobe;/* BPF_LINK_PERF_EVENT_UPROBE */+struct{+__aligned_u64func_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u64addr;+__u32flags;+}kprobe;/* BPF_LINK_PERF_EVENT_KPROBE */+struct{+__aligned_u64tp_name;/* in/out: buff ptr */+__u32name_len;+}tracepoint;/* BPF_LINK_PERF_EVENT_TRACEPOINT */};+__u32perf_link_type;/* enum bpf_perf_link_type */
I think put perf_link_type into each indivual struct is better.
It won't increase the bpf_link_info struct size. It will allow
extensions for all structs in the big union (raw_tracepoint,
tracing, cgroup, iter, ..., kprobe_multi, ...) etc.
} __attribute__((aligned(8)));
/* User bpf_sock_addr struct to access socket fields and sockaddr struct passed
On Tue, Jun 13, 2023 at 1:36 AM Yonghong Song [off-list ref] wrote:
On 6/12/23 8:16 AM, Yafang Shao wrote:
quoted
By introducing support for ->fill_link_info to the perf_event link, users
gain the ability to inspect it using `bpftool link show`. While the current
approach involves accessing this information via `bpftool perf show`,
consolidating link information for all link types in one place offers
greater convenience. Additionally, this patch extends support to the
generic perf event, which is not currently accommodated by
`bpftool perf show`. While only the perf type and config are exposed to
userspace, other attributes such as sample_period and sample_freq are
ignored. It's important to note that if kptr_restrict is not permitted, the
probed address will not be exposed, maintaining security measures.
A new enum bpf_link_perf_event_type is introduced to help the user
understand which struct is relevant.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 32 +++++++++++
kernel/bpf/syscall.c | 124 +++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 32 +++++++++++
3 files changed, 188 insertions(+)
@@ -1056,6 +1056,16 @@ enum bpf_link_type {MAX_BPF_LINK_TYPE,};+enumbpf_perf_link_type{+BPF_PERF_LINK_UNSPEC=0,+BPF_PERF_LINK_UPROBE=1,+BPF_PERF_LINK_KPROBE=2,+BPF_PERF_LINK_TRACEPOINT=3,+BPF_PERF_LINK_PERF_EVENT=4,++MAX_BPF_LINK_PERF_EVENT_TYPE,+};+/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command**NONE(default):Nofurtherbpfprogramsallowedinthesubtree.
@@ -6443,7 +6453,29 @@ struct bpf_link_info {__u32count;__u32flags;}kprobe_multi;+struct{+__u64config;+__u32type;+}perf_event;/* BPF_LINK_PERF_EVENT_PERF_EVENT */+struct{+__aligned_u64file_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u32flags;+}uprobe;/* BPF_LINK_PERF_EVENT_UPROBE */+struct{+__aligned_u64func_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u64addr;+__u32flags;+}kprobe;/* BPF_LINK_PERF_EVENT_KPROBE */+struct{+__aligned_u64tp_name;/* in/out: buff ptr */+__u32name_len;+}tracepoint;/* BPF_LINK_PERF_EVENT_TRACEPOINT */};+__u32perf_link_type;/* enum bpf_perf_link_type */
I think put perf_link_type into each indivual struct is better.
It won't increase the bpf_link_info struct size. It will allow
extensions for all structs in the big union (raw_tracepoint,
tracing, cgroup, iter, ..., kprobe_multi, ...) etc.
If we put it into each individual struct, we have to choose one
specific struct to get the type before we use the real struct, for
example,
if (info.perf_event.type == BPF_PERF_LINK_PERF_EVENT)
goto out;
if (info.perf_event.type == BPF_PERF_LINK_TRACEPOINT &&
!info.tracepoint.tp_name) {
info.tracepoint.tp_name = (unsigned long)&buf;
info.tracepoint.name_len = sizeof(buf);
goto again;
}
...
That doesn't look perfect.
However I agree with you that the perf_link_type may disallow the
extensions for the big union. I will think about it.
--
Regards
Yafang
From: Kui-Feng Lee <hidden> Date: 2023-06-14 02:34:47
On 6/12/23 19:47, Yafang Shao wrote:
On Tue, Jun 13, 2023 at 1:36 AM Yonghong Song [off-list ref] wrote:
quoted
On 6/12/23 8:16 AM, Yafang Shao wrote:
quoted
By introducing support for ->fill_link_info to the perf_event link, users
gain the ability to inspect it using `bpftool link show`. While the current
approach involves accessing this information via `bpftool perf show`,
consolidating link information for all link types in one place offers
greater convenience. Additionally, this patch extends support to the
generic perf event, which is not currently accommodated by
`bpftool perf show`. While only the perf type and config are exposed to
userspace, other attributes such as sample_period and sample_freq are
ignored. It's important to note that if kptr_restrict is not permitted, the
probed address will not be exposed, maintaining security measures.
A new enum bpf_link_perf_event_type is introduced to help the user
understand which struct is relevant.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 32 +++++++++++
kernel/bpf/syscall.c | 124 +++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 32 +++++++++++
3 files changed, 188 insertions(+)
@@ -1056,6 +1056,16 @@ enum bpf_link_type {MAX_BPF_LINK_TYPE,};+enumbpf_perf_link_type{+BPF_PERF_LINK_UNSPEC=0,+BPF_PERF_LINK_UPROBE=1,+BPF_PERF_LINK_KPROBE=2,+BPF_PERF_LINK_TRACEPOINT=3,+BPF_PERF_LINK_PERF_EVENT=4,++MAX_BPF_LINK_PERF_EVENT_TYPE,+};+/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command**NONE(default):Nofurtherbpfprogramsallowedinthesubtree.
@@ -6443,7 +6453,29 @@ struct bpf_link_info {__u32count;__u32flags;}kprobe_multi;+struct{+__u64config;+__u32type;+}perf_event;/* BPF_LINK_PERF_EVENT_PERF_EVENT */+struct{+__aligned_u64file_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u32flags;+}uprobe;/* BPF_LINK_PERF_EVENT_UPROBE */+struct{+__aligned_u64func_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u64addr;+__u32flags;+}kprobe;/* BPF_LINK_PERF_EVENT_KPROBE */+struct{+__aligned_u64tp_name;/* in/out: buff ptr */+__u32name_len;+}tracepoint;/* BPF_LINK_PERF_EVENT_TRACEPOINT */};+__u32perf_link_type;/* enum bpf_perf_link_type */
I think put perf_link_type into each indivual struct is better.
It won't increase the bpf_link_info struct size. It will allow
extensions for all structs in the big union (raw_tracepoint,
tracing, cgroup, iter, ..., kprobe_multi, ...) etc.
If we put it into each individual struct, we have to choose one
specific struct to get the type before we use the real struct, for
example,
if (info.perf_event.type == BPF_PERF_LINK_PERF_EVENT)
goto out;
if (info.perf_event.type == BPF_PERF_LINK_TRACEPOINT &&
!info.tracepoint.tp_name) {
info.tracepoint.tp_name = (unsigned long)&buf;
info.tracepoint.name_len = sizeof(buf);
goto again;
}
...
That doesn't look perfect.
How about adding a common struct?
struct {
__u32 type;
} perf_common;
Then you check info.perf_common.type.
However I agree with you that the perf_link_type may disallow the
extensions for the big union. I will think about it.
On Wed, Jun 14, 2023 at 10:34 AM Kui-Feng Lee [off-list ref] wrote:
On 6/12/23 19:47, Yafang Shao wrote:
quoted
On Tue, Jun 13, 2023 at 1:36 AM Yonghong Song [off-list ref] wrote:
quoted
On 6/12/23 8:16 AM, Yafang Shao wrote:
quoted
By introducing support for ->fill_link_info to the perf_event link, users
gain the ability to inspect it using `bpftool link show`. While the current
approach involves accessing this information via `bpftool perf show`,
consolidating link information for all link types in one place offers
greater convenience. Additionally, this patch extends support to the
generic perf event, which is not currently accommodated by
`bpftool perf show`. While only the perf type and config are exposed to
userspace, other attributes such as sample_period and sample_freq are
ignored. It's important to note that if kptr_restrict is not permitted, the
probed address will not be exposed, maintaining security measures.
A new enum bpf_link_perf_event_type is introduced to help the user
understand which struct is relevant.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 32 +++++++++++
kernel/bpf/syscall.c | 124 +++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 32 +++++++++++
3 files changed, 188 insertions(+)
@@ -1056,6 +1056,16 @@ enum bpf_link_type {MAX_BPF_LINK_TYPE,};+enumbpf_perf_link_type{+BPF_PERF_LINK_UNSPEC=0,+BPF_PERF_LINK_UPROBE=1,+BPF_PERF_LINK_KPROBE=2,+BPF_PERF_LINK_TRACEPOINT=3,+BPF_PERF_LINK_PERF_EVENT=4,++MAX_BPF_LINK_PERF_EVENT_TYPE,+};+/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command**NONE(default):Nofurtherbpfprogramsallowedinthesubtree.
@@ -6443,7 +6453,29 @@ struct bpf_link_info {__u32count;__u32flags;}kprobe_multi;+struct{+__u64config;+__u32type;+}perf_event;/* BPF_LINK_PERF_EVENT_PERF_EVENT */+struct{+__aligned_u64file_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u32flags;+}uprobe;/* BPF_LINK_PERF_EVENT_UPROBE */+struct{+__aligned_u64func_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u64addr;+__u32flags;+}kprobe;/* BPF_LINK_PERF_EVENT_KPROBE */+struct{+__aligned_u64tp_name;/* in/out: buff ptr */+__u32name_len;+}tracepoint;/* BPF_LINK_PERF_EVENT_TRACEPOINT */};+__u32perf_link_type;/* enum bpf_perf_link_type */
I think put perf_link_type into each indivual struct is better.
It won't increase the bpf_link_info struct size. It will allow
extensions for all structs in the big union (raw_tracepoint,
tracing, cgroup, iter, ..., kprobe_multi, ...) etc.
If we put it into each individual struct, we have to choose one
specific struct to get the type before we use the real struct, for
example,
if (info.perf_event.type == BPF_PERF_LINK_PERF_EVENT)
goto out;
if (info.perf_event.type == BPF_PERF_LINK_TRACEPOINT &&
!info.tracepoint.tp_name) {
info.tracepoint.tp_name = (unsigned long)&buf;
info.tracepoint.name_len = sizeof(buf);
goto again;
}
...
That doesn't look perfect.
How about adding a common struct?
struct {
__u32 type;
} perf_common;
Then you check info.perf_common.type.
On Tue, Jun 13, 2023 at 7:46 PM Yafang Shao [off-list ref] wrote:
On Wed, Jun 14, 2023 at 10:34 AM Kui-Feng Lee [off-list ref] wrote:
quoted
On 6/12/23 19:47, Yafang Shao wrote:
quoted
On Tue, Jun 13, 2023 at 1:36 AM Yonghong Song [off-list ref] wrote:
quoted
On 6/12/23 8:16 AM, Yafang Shao wrote:
quoted
By introducing support for ->fill_link_info to the perf_event link, users
gain the ability to inspect it using `bpftool link show`. While the current
approach involves accessing this information via `bpftool perf show`,
consolidating link information for all link types in one place offers
greater convenience. Additionally, this patch extends support to the
generic perf event, which is not currently accommodated by
`bpftool perf show`. While only the perf type and config are exposed to
userspace, other attributes such as sample_period and sample_freq are
ignored. It's important to note that if kptr_restrict is not permitted, the
probed address will not be exposed, maintaining security measures.
A new enum bpf_link_perf_event_type is introduced to help the user
understand which struct is relevant.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 32 +++++++++++
kernel/bpf/syscall.c | 124 +++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 32 +++++++++++
3 files changed, 188 insertions(+)
@@ -1056,6 +1056,16 @@ enum bpf_link_type {MAX_BPF_LINK_TYPE,};+enumbpf_perf_link_type{+BPF_PERF_LINK_UNSPEC=0,+BPF_PERF_LINK_UPROBE=1,+BPF_PERF_LINK_KPROBE=2,+BPF_PERF_LINK_TRACEPOINT=3,+BPF_PERF_LINK_PERF_EVENT=4,++MAX_BPF_LINK_PERF_EVENT_TYPE,+};+/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command**NONE(default):Nofurtherbpfprogramsallowedinthesubtree.
@@ -6443,7 +6453,29 @@ struct bpf_link_info {__u32count;__u32flags;}kprobe_multi;+struct{+__u64config;+__u32type;+}perf_event;/* BPF_LINK_PERF_EVENT_PERF_EVENT */+struct{+__aligned_u64file_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u32flags;+}uprobe;/* BPF_LINK_PERF_EVENT_UPROBE */+struct{+__aligned_u64func_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u64addr;+__u32flags;+}kprobe;/* BPF_LINK_PERF_EVENT_KPROBE */+struct{+__aligned_u64tp_name;/* in/out: buff ptr */+__u32name_len;+}tracepoint;/* BPF_LINK_PERF_EVENT_TRACEPOINT */};+__u32perf_link_type;/* enum bpf_perf_link_type */
I think put perf_link_type into each indivual struct is better.
It won't increase the bpf_link_info struct size. It will allow
extensions for all structs in the big union (raw_tracepoint,
tracing, cgroup, iter, ..., kprobe_multi, ...) etc.
If we put it into each individual struct, we have to choose one
specific struct to get the type before we use the real struct, for
example,
if (info.perf_event.type == BPF_PERF_LINK_PERF_EVENT)
goto out;
if (info.perf_event.type == BPF_PERF_LINK_TRACEPOINT &&
!info.tracepoint.tp_name) {
info.tracepoint.tp_name = (unsigned long)&buf;
info.tracepoint.name_len = sizeof(buf);
goto again;
}
...
That doesn't look perfect.
How about adding a common struct?
struct {
__u32 type;
} perf_common;
Then you check info.perf_common.type.
this should be named "perf_event" to match BPF_LINK_TYPE_PERF_EVENT
and "perf_event" above probably could be just "event" then? Similarly
we can s/BPF_PERF_LINK_PERF_EVENT/BPF_PERF_LINK_EVENT/?
I think that would be more clear.
--
Regards
Yafang
On Sat, Jun 17, 2023 at 4:36 AM Andrii Nakryiko
[off-list ref] wrote:
On Tue, Jun 13, 2023 at 7:46 PM Yafang Shao [off-list ref] wrote:
quoted
On Wed, Jun 14, 2023 at 10:34 AM Kui-Feng Lee [off-list ref] wrote:
quoted
On 6/12/23 19:47, Yafang Shao wrote:
quoted
On Tue, Jun 13, 2023 at 1:36 AM Yonghong Song [off-list ref] wrote:
quoted
On 6/12/23 8:16 AM, Yafang Shao wrote:
quoted
By introducing support for ->fill_link_info to the perf_event link, users
gain the ability to inspect it using `bpftool link show`. While the current
approach involves accessing this information via `bpftool perf show`,
consolidating link information for all link types in one place offers
greater convenience. Additionally, this patch extends support to the
generic perf event, which is not currently accommodated by
`bpftool perf show`. While only the perf type and config are exposed to
userspace, other attributes such as sample_period and sample_freq are
ignored. It's important to note that if kptr_restrict is not permitted, the
probed address will not be exposed, maintaining security measures.
A new enum bpf_link_perf_event_type is introduced to help the user
understand which struct is relevant.
Signed-off-by: Yafang Shao <redacted>
---
include/uapi/linux/bpf.h | 32 +++++++++++
kernel/bpf/syscall.c | 124 +++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 32 +++++++++++
3 files changed, 188 insertions(+)
@@ -1056,6 +1056,16 @@ enum bpf_link_type {MAX_BPF_LINK_TYPE,};+enumbpf_perf_link_type{+BPF_PERF_LINK_UNSPEC=0,+BPF_PERF_LINK_UPROBE=1,+BPF_PERF_LINK_KPROBE=2,+BPF_PERF_LINK_TRACEPOINT=3,+BPF_PERF_LINK_PERF_EVENT=4,++MAX_BPF_LINK_PERF_EVENT_TYPE,+};+/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command**NONE(default):Nofurtherbpfprogramsallowedinthesubtree.
@@ -6443,7 +6453,29 @@ struct bpf_link_info {__u32count;__u32flags;}kprobe_multi;+struct{+__u64config;+__u32type;+}perf_event;/* BPF_LINK_PERF_EVENT_PERF_EVENT */+struct{+__aligned_u64file_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u32flags;+}uprobe;/* BPF_LINK_PERF_EVENT_UPROBE */+struct{+__aligned_u64func_name;/* in/out: buff ptr */+__u32name_len;+__u32offset;/* offset from name */+__u64addr;+__u32flags;+}kprobe;/* BPF_LINK_PERF_EVENT_KPROBE */+struct{+__aligned_u64tp_name;/* in/out: buff ptr */+__u32name_len;+}tracepoint;/* BPF_LINK_PERF_EVENT_TRACEPOINT */};+__u32perf_link_type;/* enum bpf_perf_link_type */
I think put perf_link_type into each indivual struct is better.
It won't increase the bpf_link_info struct size. It will allow
extensions for all structs in the big union (raw_tracepoint,
tracing, cgroup, iter, ..., kprobe_multi, ...) etc.
If we put it into each individual struct, we have to choose one
specific struct to get the type before we use the real struct, for
example,
if (info.perf_event.type == BPF_PERF_LINK_PERF_EVENT)
goto out;
if (info.perf_event.type == BPF_PERF_LINK_TRACEPOINT &&
!info.tracepoint.tp_name) {
info.tracepoint.tp_name = (unsigned long)&buf;
info.tracepoint.name_len = sizeof(buf);
goto again;
}
...
That doesn't look perfect.
How about adding a common struct?
struct {
__u32 type;
} perf_common;
Then you check info.perf_common.type.
this should be named "perf_event" to match BPF_LINK_TYPE_PERF_EVENT
and "perf_event" above probably could be just "event" then? Similarly
we can s/BPF_PERF_LINK_PERF_EVENT/BPF_PERF_LINK_EVENT/?
Add new functions and macros to get perf event names. These names are
copied from tool/perf/util/{parse-events,evsel}.c, so that in the future we
will have a good chance to use the same code.
Suggested-by: Jiri Olsa <redacted>
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/perf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++
tools/bpf/bpftool/perf.h | 11 +++++
2 files changed, 118 insertions(+)
create mode 100644 tools/bpf/bpftool/perf.h
Add new functions and macros to get perf event names. These names are
copied from tool/perf/util/{parse-events,evsel}.c, so that in the future we
will have a good chance to use the same code.
Suggested-by: Jiri Olsa <redacted>
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/perf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++
tools/bpf/bpftool/perf.h | 11 +++++
Although the names are deceiving, I think these should all be moved to
link.c and link.h, where we'll actually use them, or to some other file
with a new name. File perf.c is for implementing "bpftool perf ...".
I'm not sure we need all these API functions if we keep the arrays in
bpftool. I'd probably have just a generic one and pass it the name of
the relevant array in argument. Although I've got no objection with the
current form if it helps unifying the code with perf in the future.
Add new functions and macros to get perf event names. These names are
copied from tool/perf/util/{parse-events,evsel}.c, so that in the future we
will have a good chance to use the same code.
Suggested-by: Jiri Olsa <redacted>
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/perf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++
tools/bpf/bpftool/perf.h | 11 +++++
Although the names are deceiving, I think these should all be moved to
link.c and link.h, where we'll actually use them, or to some other file
with a new name. File perf.c is for implementing "bpftool perf ...".
I'm not sure we need all these API functions if we keep the arrays in
bpftool. I'd probably have just a generic one and pass it the name of
the relevant array in argument. Although I've got no objection with the
current form if it helps unifying the code with perf in the future.
Sure, I will use a generic one instead.
--
Regards
Yafang
From: Jiri Olsa <hidden> Date: 2023-06-15 10:23:19
On Mon, Jun 12, 2023 at 03:16:07PM +0000, Yafang Shao wrote:
quoted hunk
Add new functions and macros to get perf event names. These names are
copied from tool/perf/util/{parse-events,evsel}.c, so that in the future we
will have a good chance to use the same code.
Suggested-by: Jiri Olsa <redacted>
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/perf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++
tools/bpf/bpftool/perf.h | 11 +++++
2 files changed, 118 insertions(+)
create mode 100644 tools/bpf/bpftool/perf.h
Could we swap the name and the address, for consistency with the
kprobe_multi case?
Also do we really need the "_name" suffix in "func_name" and "file_name"
for plain output? I don't mind in JSON, but I think the result is a bit
long for plain output.
quoted hunk
bpf_cookie 0
pids kprobe(1384186)
11: perf_event prog 41
retprobe 1 func_name kernel_clone addr ffffffffad0a9660
bpf_cookie 0
pids kprobe(1384186)
$ tools/bpf/bpftool/bpftool link show -j
[{"id":3,"type":"perf_event","prog_id":14,"event_type":"software","event_config":"cpu-clock","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":4,"type":"perf_event","prog_id":14,"event_type":"hw-cache","event_config":"LLC-load-misses","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":5,"type":"perf_event","prog_id":14,"event_type":"hardware","event_config":"cpu-cycles","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":6,"type":"perf_event","prog_id":20,"retprobe":0,"file_name":"/home/yafang/bpf/uprobe/a.out","offset":4920,"bpf_cookie":0,"pids":[{"pid":1379706,"comm":"uprobe"}]},{"id":7,"type":"perf_event","prog_id":21,"retprobe":1,"file_name":"/home/yafang/bpf/uprobe/a.out","offset":4920,"bpf_cookie":0,"pids":[{"pid":1379706,"comm":"uprobe"}]},{"id":8,"type":"perf_event","prog_id":27,"tp_name":"sched_switch","bpf_cookie":0,"pids":[{"pid":1381734,"comm":"tracepoint"}]},{"id":10,"type":"perf_event","prog_id":43,"retprobe":0,"func_name":"kernel_clone","offset":0,"addr":18446744072317736544,"bpf_cookie":0,"pids":[{"pid":1384186,"comm":"kprobe"}]},{"id":11,"type":"perf_event","prog_id":41,"retprobe":1,"func_name":"kernel_clone","offset":0,"addr":18446744072317736544,"bpf_cookie":0,"pids":[{"pid":1384186,"comm":"kprobe"}]}]
For generic perf events, the displayed information in bpftool is limited to
the type and configuration, while other attributes such as sample_period,
sample_freq, etc., are not included.
The kernel function address won't be exposed if it is not permitted by
kptr_restrict. The result as follows when kptr_restrict is 2.
$ tools/bpf/bpftool/bpftool link show
3: perf_event prog 14
event_type software event_config cpu-clock
4: perf_event prog 14
event_type hw-cache event_config LLC-load-misses
5: perf_event prog 14
event_type hardware event_config cpu-cycles
6: perf_event prog 20
retprobe 0 file_name /home/yafang/bpf/uprobe/a.out offset 0x1338
7: perf_event prog 21
retprobe 1 file_name /home/yafang/bpf/uprobe/a.out offset 0x1338
8: perf_event prog 27
tp_name sched_switch
10: perf_event prog 43
retprobe 0 func_name kernel_clone
11: perf_event prog 41
retprobe 1 func_name kernel_clone
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/link.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 213 insertions(+)
Could we swap the name and the address, for consistency with the
kprobe_multi case?
Agree. Will change it.
Also do we really need the "_name" suffix in "func_name" and "file_name"
for plain output? I don't mind in JSON, but I think the result is a bit
long for plain output.
They are really a bit long. Will remove the "_name" suffix.
quoted
bpf_cookie 0
pids kprobe(1384186)
11: perf_event prog 41
retprobe 1 func_name kernel_clone addr ffffffffad0a9660
bpf_cookie 0
pids kprobe(1384186)
$ tools/bpf/bpftool/bpftool link show -j
[{"id":3,"type":"perf_event","prog_id":14,"event_type":"software","event_config":"cpu-clock","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":4,"type":"perf_event","prog_id":14,"event_type":"hw-cache","event_config":"LLC-load-misses","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":5,"type":"perf_event","prog_id":14,"event_type":"hardware","event_config":"cpu-cycles","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":6,"type":"perf_event","prog_id":20,"retprobe":0,"file_name":"/home/yafang/bpf/uprobe/a.out","offset":4920,"bpf_cookie":0,"pids":[{"pid":1379706,"comm":"uprobe"}]},{"id":7,"type":"perf_event","prog_id":21,"retprobe":1,"file_name":"/home/yafang/bpf/uprobe/a.out","offset":4920,"bpf_cookie":0,"pids":[{"pid":1379706,"comm":"uprobe"}]},{"id":8,"type":"perf_event","prog_id":27,"tp_name":"sched_switch","bpf_cookie":0,"pids":[{"pid":1381734,"comm":"tracepoint"}]},{"id":10,"type":"perf_event","prog_id":43,"retprobe":0,"func_name":"kernel_clone","offset":0,"addr":18446744072317736544,"bpf_cookie":0,"pids":[{"pid":1384186,"comm":"kprobe"}]},{"id":11,"type":"perf_event","prog_id":41,"retprobe":1,"func_name":"kernel_clone","offset":0,"addr":18446744072317736544,"bpf_cookie":0,"pids":[{"pid":1384186,"comm":"kprobe"}]}]
For generic perf events, the displayed information in bpftool is limited to
the type and configuration, while other attributes such as sample_period,
sample_freq, etc., are not included.
The kernel function address won't be exposed if it is not permitted by
kptr_restrict. The result as follows when kptr_restrict is 2.
$ tools/bpf/bpftool/bpftool link show
3: perf_event prog 14
event_type software event_config cpu-clock
4: perf_event prog 14
event_type hw-cache event_config LLC-load-misses
5: perf_event prog 14
event_type hardware event_config cpu-cycles
6: perf_event prog 20
retprobe 0 file_name /home/yafang/bpf/uprobe/a.out offset 0x1338
7: perf_event prog 21
retprobe 1 file_name /home/yafang/bpf/uprobe/a.out offset 0x1338
8: perf_event prog 27
tp_name sched_switch
10: perf_event prog 43
retprobe 0 func_name kernel_clone
11: perf_event prog 41
retprobe 1 func_name kernel_clone
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/link.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 213 insertions(+)
similar to uprobes:
"kprobe kernel_clone 0xffffffffad0a9660"
"kretprobe kernel_clone 0xffffffffad0a9660"
That is, make this more human readable instead of mechanically
translated from kernel info? retprobe 1/0 is quite cumbersome,
"uprobe" vs "uretprobe" makes more sense?
JSON is where it could be completely mechanically translated, IMO.
bpf_cookie 0
pids kprobe(1384186)
11: perf_event prog 41
retprobe 1 func_name kernel_clone addr ffffffffad0a9660
bpf_cookie 0
pids kprobe(1384186)
$ tools/bpf/bpftool/bpftool link show -j
[{"id":3,"type":"perf_event","prog_id":14,"event_type":"software","event_config":"cpu-clock","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":4,"type":"perf_event","prog_id":14,"event_type":"hw-cache","event_config":"LLC-load-misses","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":5,"type":"perf_event","prog_id":14,"event_type":"hardware","event_config":"cpu-cycles","bpf_cookie":0,"pids":[{"pid":1379330,"comm":"perf_event"}]},{"id":6,"type":"perf_event","prog_id":20,"retprobe":0,"file_name":"/home/yafang/bpf/uprobe/a.out","offset":4920,"bpf_cookie":0,"pids":[{"pid":1379706,"comm":"uprobe"}]},{"id":7,"type":"perf_event","prog_id":21,"retprobe":1,"file_name":"/home/yafang/bpf/uprobe/a.out","offset":4920,"bpf_cookie":0,"pids":[{"pid":1379706,"comm":"uprobe"}]},{"id":8,"type":"perf_event","prog_id":27,"tp_name":"sched_switch","bpf_cookie":0,"pids":[{"pid":1381734,"comm":"tracepoint"}]},{"id":10,"type":"perf_event","prog_id":43,"retprobe":0,"func_name":"kernel_clone","offset":0,"addr":18446744072317736544,"bpf_cookie":0,"pids":[{"pid":1384186,"comm":"kprobe"}]},{"id":11,"type":"perf_event","prog_id":41,"retprobe":1,"func_name":"kernel_clone","offset":0,"addr":18446744072317736544,"bpf_cookie":0,"pids":[{"pid":1384186,"comm":"kprobe"}]}]
For generic perf events, the displayed information in bpftool is limited to
the type and configuration, while other attributes such as sample_period,
sample_freq, etc., are not included.
The kernel function address won't be exposed if it is not permitted by
kptr_restrict. The result as follows when kptr_restrict is 2.
$ tools/bpf/bpftool/bpftool link show
3: perf_event prog 14
event_type software event_config cpu-clock
4: perf_event prog 14
event_type hw-cache event_config LLC-load-misses
5: perf_event prog 14
event_type hardware event_config cpu-cycles
6: perf_event prog 20
retprobe 0 file_name /home/yafang/bpf/uprobe/a.out offset 0x1338
7: perf_event prog 21
retprobe 1 file_name /home/yafang/bpf/uprobe/a.out offset 0x1338
8: perf_event prog 27
tp_name sched_switch
10: perf_event prog 43
retprobe 0 func_name kernel_clone
11: perf_event prog 41
retprobe 1 func_name kernel_clone
Signed-off-by: Yafang Shao <redacted>
---
tools/bpf/bpftool/link.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 213 insertions(+)
similar to uprobes:
"kprobe kernel_clone 0xffffffffad0a9660"
"kretprobe kernel_clone 0xffffffffad0a9660"
That is, make this more human readable instead of mechanically
translated from kernel info? retprobe 1/0 is quite cumbersome,
"uprobe" vs "uretprobe" makes more sense?
Agree. Will do it.
JSON is where it could be completely mechanically translated, IMO.
similar to uprobes:
"kprobe kernel_clone 0xffffffffad0a9660"
"kretprobe kernel_clone 0xffffffffad0a9660"
That is, make this more human readable instead of mechanically
translated from kernel info? retprobe 1/0 is quite cumbersome,
"uprobe" vs "uretprobe" makes more sense?
Agree. Will do it.
quoted
JSON is where it could be completely mechanically translated, IMO.
From: Jiri Olsa <hidden> Date: 2023-06-15 10:04:28
On Mon, Jun 12, 2023 at 03:15:58PM +0000, Yafang Shao wrote:
This patchset enhances the usability of kprobe_multi programs by introducing
support for ->fill_link_info. This allows users to easily determine the
probed functions associated with a kprobe_multi program. While
`bpftool perf show` already provides information about functions probed by
perf_event programs, supporting ->fill_link_info ensures consistent access to
this information across all bpf links.
In addition, this patch extends support to generic perf events, which are
currently not covered by `bpftool perf show`. While userspace is exposed to
only the perf type and config, other attributes such as sample_period and
sample_freq are disregarded.
To ensure accurate identification of probed functions, it is preferable to
expose the address directly rather than relying solely on the symbol name.
However, this implementation respects the kptr_restrict setting and avoids
exposing the address if it is not permitted.
v2->v3:
- Expose flags instead of retporbe (Andrii)
- Simplify the check on kmulti_link->cnt (Andrii)
- Use kallsyms_show_value() instead (Andrii)
- Show also the module name for kprobe_multi (Andrii)
- Add new enum bpf_perf_link_type (Andrii)
- Move perf event names into bpftool (Andrii, Quentin, Jiri)
- Keep perf event names in sync with perf tools (Jiri)
v1->v2:
- Fix sparse warning (Stanislav, lkp@intel.com)
- Fix BPF CI build error
- Reuse kernel_syms_load() (Alexei)
- Print 'name' instead of 'func' (Alexei)
- Show whether the probe is retprobe or not (Andrii)
- Add comment for the meaning of perf_event name (Andrii)
- Add support for generic perf event
- Adhere to the kptr_restrict setting
RFC->v1:
- Use a single copy_to_user() instead (Jiri)
- Show also the symbol name in bpftool (Quentin, Alexei)
- Use calloc() instead of malloc() in bpftool (Quentin)
- Avoid having conditional entries in the JSON output (Quentin)
- Drop ->show_fdinfo (Alexei)
- Use __u64 instead of __aligned_u64 for the field addr (Alexei)
- Avoid the contradiction in perf_event name length (Alexei)
- Address a build warning reported by kernel test robot [off-list ref]
Yafang Shao (10):
bpf: Support ->fill_link_info for kprobe_multi
bpftool: Dump the kernel symbol's module name
bpftool: Show probed function in kprobe_multi link info
bpf: Protect probed address based on kptr_restrict setting
bpf: Clear the probe_addr for uprobe
bpf: Expose symbol's respective address
bpf: Add a common helper bpf_copy_to_user()
bpf: Support ->fill_link_info for perf_event
bpftool: Add perf event names
bpftool: Show probed function in perf_event link info
include/uapi/linux/bpf.h | 37 +++++
kernel/bpf/syscall.c | 158 +++++++++++++++++--
kernel/trace/bpf_trace.c | 32 +++-
kernel/trace/trace_kprobe.c | 7 +-
tools/bpf/bpftool/link.c | 322 +++++++++++++++++++++++++++++++++++++-
tools/bpf/bpftool/perf.c | 107 +++++++++++++
tools/bpf/bpftool/perf.h | 11 ++
tools/bpf/bpftool/xlated_dumper.c | 6 +-
tools/bpf/bpftool/xlated_dumper.h | 2 +
tools/include/uapi/linux/bpf.h | 37 +++++
10 files changed, 700 insertions(+), 19 deletions(-)
create mode 100644 tools/bpf/bpftool/perf.h
--
1.8.3.1
On Thu, Jun 15, 2023 at 6:04 PM Jiri Olsa [off-list ref] wrote:
On Mon, Jun 12, 2023 at 03:15:58PM +0000, Yafang Shao wrote:
quoted
This patchset enhances the usability of kprobe_multi programs by introducing
support for ->fill_link_info. This allows users to easily determine the
probed functions associated with a kprobe_multi program. While
`bpftool perf show` already provides information about functions probed by
perf_event programs, supporting ->fill_link_info ensures consistent access to
this information across all bpf links.
In addition, this patch extends support to generic perf events, which are
currently not covered by `bpftool perf show`. While userspace is exposed to
only the perf type and config, other attributes such as sample_period and
sample_freq are disregarded.
To ensure accurate identification of probed functions, it is preferable to
expose the address directly rather than relying solely on the symbol name.
However, this implementation respects the kptr_restrict setting and avoids
exposing the address if it is not permitted.
v2->v3:
- Expose flags instead of retporbe (Andrii)
- Simplify the check on kmulti_link->cnt (Andrii)
- Use kallsyms_show_value() instead (Andrii)
- Show also the module name for kprobe_multi (Andrii)
- Add new enum bpf_perf_link_type (Andrii)
- Move perf event names into bpftool (Andrii, Quentin, Jiri)
- Keep perf event names in sync with perf tools (Jiri)
Thanks for your report.
BPF CI catched these errors as well.
That is caused by setting link->fp.flags, which has been pointed out
by you in patch #1.
I will fix it in the next version.
--
Regards
Yafang