Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'libbpf-fix-event-name-too-long-error-and-add-tests'

Feng Yang says:

====================
libbpf: Fix event name too long error and add tests

From: Feng Yang <yangfeng@kylinos.cn>

Hi everyone,

This series tries to fix event name too long error and add tests.

When the binary path is excessively long, the generated probe_name in libbpf
exceeds the kernel's MAX_EVENT_NAME_LEN limit (64 bytes).
This causes legacy uprobe event attachment to fail with error code -22.

The fix reorders the fields to place the unique ID before the name.
This ensures that even if truncation occurs via snprintf, the unique ID
remains intact, preserving event name uniqueness. Additionally, explicit
checks with MAX_EVENT_NAME_LEN are added to enforce length constraints.
Acked-by: Jiri Olsa <jolsa@kernel.org>
---
Changes in v5:
- use strrchr instead of basename.
- kprobe_test add __weak. Thanks, Andrii Nakryiko!
- Link to v4: https://lore.kernel.org/all/20250415093907.280501-1-yangfeng59949@163.com/

Changes in v4:
- add changelog.
- gen_uprobe_legacy_event_name and gen_kprobe_legacy_event_name are combined into a function
- kprobe_test use normal module function. Thanks, Jiri Olsa!
- Link to v3: https://lore.kernel.org/bpf/20250414093402.384872-1-yangfeng59949@163.com/

Changes in v3:
- add __sync_fetch_and_add(&index) and let snprintf() do the trimming. Thanks, Andrii Nakryiko!
- add selftests.
- Link to v2: https://lore.kernel.org/all/20250411080545.319865-1-yangfeng59949@163.com/

Changes in v2:
- Use basename() and %.32s to fix. Thanks, Hengqi Chen!
- Link to v1: https://lore.kernel.org/all/20250410052712.206785-1-yangfeng59949@163.com/
====================

Link: https://patch.msgid.link/20250417014848.59321-1-yangfeng59949@163.com
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

+104 -27
+16 -27
tools/lib/bpf/libbpf.c
··· 60 60 #define BPF_FS_MAGIC 0xcafe4a11 61 61 #endif 62 62 63 + #define MAX_EVENT_NAME_LEN 64 64 + 63 65 #define BPF_FS_DEFAULT_PATH "/sys/fs/bpf" 64 66 65 67 #define BPF_INSN_SZ (sizeof(struct bpf_insn)) ··· 11138 11136 : TRACEFS"/available_filter_functions_addrs"; 11139 11137 } 11140 11138 11141 - static void gen_kprobe_legacy_event_name(char *buf, size_t buf_sz, 11142 - const char *kfunc_name, size_t offset) 11139 + static void gen_probe_legacy_event_name(char *buf, size_t buf_sz, 11140 + const char *name, size_t offset) 11143 11141 { 11144 11142 static int index = 0; 11145 11143 int i; 11146 11144 11147 - snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx_%d", getpid(), kfunc_name, offset, 11148 - __sync_fetch_and_add(&index, 1)); 11145 + snprintf(buf, buf_sz, "libbpf_%u_%d_%s_0x%zx", getpid(), 11146 + __sync_fetch_and_add(&index, 1), name, offset); 11149 11147 11150 - /* sanitize binary_path in the probe name */ 11148 + /* sanitize name in the probe name */ 11151 11149 for (i = 0; buf[i]; i++) { 11152 11150 if (!isalnum(buf[i])) 11153 11151 buf[i] = '_'; ··· 11272 11270 11273 11271 return pfd >= 0 ? 1 : 0; 11274 11272 } else { /* legacy mode */ 11275 - char probe_name[128]; 11273 + char probe_name[MAX_EVENT_NAME_LEN]; 11276 11274 11277 - gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name), syscall_name, 0); 11275 + gen_probe_legacy_event_name(probe_name, sizeof(probe_name), syscall_name, 0); 11278 11276 if (add_kprobe_event_legacy(probe_name, false, syscall_name, 0) < 0) 11279 11277 return 0; 11280 11278 ··· 11330 11328 func_name, offset, 11331 11329 -1 /* pid */, 0 /* ref_ctr_off */); 11332 11330 } else { 11333 - char probe_name[256]; 11331 + char probe_name[MAX_EVENT_NAME_LEN]; 11334 11332 11335 - gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name), 11336 - func_name, offset); 11333 + gen_probe_legacy_event_name(probe_name, sizeof(probe_name), 11334 + func_name, offset); 11337 11335 11338 11336 legacy_probe = strdup(probe_name); 11339 11337 if (!legacy_probe) ··· 11877 11875 return ret; 11878 11876 } 11879 11877 11880 - static void gen_uprobe_legacy_event_name(char *buf, size_t buf_sz, 11881 - const char *binary_path, uint64_t offset) 11882 - { 11883 - int i; 11884 - 11885 - snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx", getpid(), binary_path, (size_t)offset); 11886 - 11887 - /* sanitize binary_path in the probe name */ 11888 - for (i = 0; buf[i]; i++) { 11889 - if (!isalnum(buf[i])) 11890 - buf[i] = '_'; 11891 - } 11892 - } 11893 - 11894 11878 static inline int add_uprobe_event_legacy(const char *probe_name, bool retprobe, 11895 11879 const char *binary_path, size_t offset) 11896 11880 { ··· 12300 12312 pfd = perf_event_open_probe(true /* uprobe */, retprobe, binary_path, 12301 12313 func_offset, pid, ref_ctr_off); 12302 12314 } else { 12303 - char probe_name[PATH_MAX + 64]; 12315 + char probe_name[MAX_EVENT_NAME_LEN]; 12304 12316 12305 12317 if (ref_ctr_off) 12306 12318 return libbpf_err_ptr(-EINVAL); 12307 12319 12308 - gen_uprobe_legacy_event_name(probe_name, sizeof(probe_name), 12309 - binary_path, func_offset); 12320 + gen_probe_legacy_event_name(probe_name, sizeof(probe_name), 12321 + strrchr(binary_path, '/') ? : binary_path, 12322 + func_offset); 12310 12323 12311 12324 legacy_probe = strdup(probe_name); 12312 12325 if (!legacy_probe)
+84
tools/testing/selftests/bpf/prog_tests/attach_probe.c
··· 122 122 test_attach_probe_manual__destroy(skel); 123 123 } 124 124 125 + /* attach uprobe/uretprobe long event name testings */ 126 + static void test_attach_uprobe_long_event_name(void) 127 + { 128 + DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); 129 + struct bpf_link *uprobe_link, *uretprobe_link; 130 + struct test_attach_probe_manual *skel; 131 + ssize_t uprobe_offset; 132 + char path[PATH_MAX] = {0}; 133 + 134 + skel = test_attach_probe_manual__open_and_load(); 135 + if (!ASSERT_OK_PTR(skel, "skel_kprobe_manual_open_and_load")) 136 + return; 137 + 138 + uprobe_offset = get_uprobe_offset(&trigger_func); 139 + if (!ASSERT_GE(uprobe_offset, 0, "uprobe_offset")) 140 + goto cleanup; 141 + 142 + if (!ASSERT_GT(readlink("/proc/self/exe", path, PATH_MAX - 1), 0, "readlink")) 143 + goto cleanup; 144 + 145 + /* manual-attach uprobe/uretprobe */ 146 + uprobe_opts.attach_mode = PROBE_ATTACH_MODE_LEGACY; 147 + uprobe_opts.ref_ctr_offset = 0; 148 + uprobe_opts.retprobe = false; 149 + uprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uprobe, 150 + 0 /* self pid */, 151 + path, 152 + uprobe_offset, 153 + &uprobe_opts); 154 + if (!ASSERT_OK_PTR(uprobe_link, "attach_uprobe_long_event_name")) 155 + goto cleanup; 156 + skel->links.handle_uprobe = uprobe_link; 157 + 158 + uprobe_opts.retprobe = true; 159 + uretprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uretprobe, 160 + -1 /* any pid */, 161 + path, 162 + uprobe_offset, &uprobe_opts); 163 + if (!ASSERT_OK_PTR(uretprobe_link, "attach_uretprobe_long_event_name")) 164 + goto cleanup; 165 + skel->links.handle_uretprobe = uretprobe_link; 166 + 167 + cleanup: 168 + test_attach_probe_manual__destroy(skel); 169 + } 170 + 171 + /* attach kprobe/kretprobe long event name testings */ 172 + static void test_attach_kprobe_long_event_name(void) 173 + { 174 + DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, kprobe_opts); 175 + struct bpf_link *kprobe_link, *kretprobe_link; 176 + struct test_attach_probe_manual *skel; 177 + 178 + skel = test_attach_probe_manual__open_and_load(); 179 + if (!ASSERT_OK_PTR(skel, "skel_kprobe_manual_open_and_load")) 180 + return; 181 + 182 + /* manual-attach kprobe/kretprobe */ 183 + kprobe_opts.attach_mode = PROBE_ATTACH_MODE_LEGACY; 184 + kprobe_opts.retprobe = false; 185 + kprobe_link = bpf_program__attach_kprobe_opts(skel->progs.handle_kprobe, 186 + "bpf_testmod_looooooooooooooooooooooooooooooong_name", 187 + &kprobe_opts); 188 + if (!ASSERT_OK_PTR(kprobe_link, "attach_kprobe_long_event_name")) 189 + goto cleanup; 190 + skel->links.handle_kprobe = kprobe_link; 191 + 192 + kprobe_opts.retprobe = true; 193 + kretprobe_link = bpf_program__attach_kprobe_opts(skel->progs.handle_kretprobe, 194 + "bpf_testmod_looooooooooooooooooooooooooooooong_name", 195 + &kprobe_opts); 196 + if (!ASSERT_OK_PTR(kretprobe_link, "attach_kretprobe_long_event_name")) 197 + goto cleanup; 198 + skel->links.handle_kretprobe = kretprobe_link; 199 + 200 + cleanup: 201 + test_attach_probe_manual__destroy(skel); 202 + } 203 + 125 204 static void test_attach_probe_auto(struct test_attach_probe *skel) 126 205 { 127 206 struct bpf_link *uprobe_err_link; ··· 401 322 test_uprobe_sleepable(skel); 402 323 if (test__start_subtest("uprobe-ref_ctr")) 403 324 test_uprobe_ref_ctr(skel); 325 + 326 + if (test__start_subtest("uprobe-long_name")) 327 + test_attach_uprobe_long_event_name(); 328 + if (test__start_subtest("kprobe-long_name")) 329 + test_attach_kprobe_long_event_name(); 404 330 405 331 cleanup: 406 332 test_attach_probe__destroy(skel);
+4
tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
··· 134 134 return bpf_testmod_test_struct_arg_result; 135 135 } 136 136 137 + __weak noinline void bpf_testmod_looooooooooooooooooooooooooooooong_name(void) 138 + { 139 + } 140 + 137 141 __bpf_kfunc void 138 142 bpf_testmod_test_mod_kfunc(int i) 139 143 {