Skip to content

Commit 5cffad0

Browse files
committed
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 <[email protected]> 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 <[email protected]> --- Changes in v5: - use strrchr instead of basename. - kprobe_test add __weak. Thanks, Andrii Nakryiko! - Link to v4: https://lore.kernel.org/all/[email protected]/ 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/[email protected]/ 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/[email protected]/ Changes in v2: - Use basename() and %.32s to fix. Thanks, Hengqi Chen! - Link to v1: https://lore.kernel.org/all/[email protected]/ ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents be2fea9 + 9b72f3e commit 5cffad0

File tree

3 files changed

+104
-27
lines changed

3 files changed

+104
-27
lines changed

tools/lib/bpf/libbpf.c

+16-27
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
#define BPF_FS_MAGIC 0xcafe4a11
6161
#endif
6262

63+
#define MAX_EVENT_NAME_LEN 64
64+
6365
#define BPF_FS_DEFAULT_PATH "/sys/fs/bpf"
6466

6567
#define BPF_INSN_SZ (sizeof(struct bpf_insn))
@@ -11136,16 +11138,16 @@ static const char *tracefs_available_filter_functions_addrs(void)
1113611138
: TRACEFS"/available_filter_functions_addrs";
1113711139
}
1113811140

11139-
static void gen_kprobe_legacy_event_name(char *buf, size_t buf_sz,
11140-
const char *kfunc_name, size_t offset)
11141+
static void gen_probe_legacy_event_name(char *buf, size_t buf_sz,
11142+
const char *name, size_t offset)
1114111143
{
1114211144
static int index = 0;
1114311145
int i;
1114411146

11145-
snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx_%d", getpid(), kfunc_name, offset,
11146-
__sync_fetch_and_add(&index, 1));
11147+
snprintf(buf, buf_sz, "libbpf_%u_%d_%s_0x%zx", getpid(),
11148+
__sync_fetch_and_add(&index, 1), name, offset);
1114711149

11148-
/* sanitize binary_path in the probe name */
11150+
/* sanitize name in the probe name */
1114911151
for (i = 0; buf[i]; i++) {
1115011152
if (!isalnum(buf[i]))
1115111153
buf[i] = '_';
@@ -11270,9 +11272,9 @@ int probe_kern_syscall_wrapper(int token_fd)
1127011272

1127111273
return pfd >= 0 ? 1 : 0;
1127211274
} else { /* legacy mode */
11273-
char probe_name[128];
11275+
char probe_name[MAX_EVENT_NAME_LEN];
1127411276

11275-
gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name), syscall_name, 0);
11277+
gen_probe_legacy_event_name(probe_name, sizeof(probe_name), syscall_name, 0);
1127611278
if (add_kprobe_event_legacy(probe_name, false, syscall_name, 0) < 0)
1127711279
return 0;
1127811280

@@ -11328,10 +11330,10 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog,
1132811330
func_name, offset,
1132911331
-1 /* pid */, 0 /* ref_ctr_off */);
1133011332
} else {
11331-
char probe_name[256];
11333+
char probe_name[MAX_EVENT_NAME_LEN];
1133211334

11333-
gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name),
11334-
func_name, offset);
11335+
gen_probe_legacy_event_name(probe_name, sizeof(probe_name),
11336+
func_name, offset);
1133511337

1133611338
legacy_probe = strdup(probe_name);
1133711339
if (!legacy_probe)
@@ -11875,20 +11877,6 @@ static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, stru
1187511877
return ret;
1187611878
}
1187711879

11878-
static void gen_uprobe_legacy_event_name(char *buf, size_t buf_sz,
11879-
const char *binary_path, uint64_t offset)
11880-
{
11881-
int i;
11882-
11883-
snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx", getpid(), binary_path, (size_t)offset);
11884-
11885-
/* sanitize binary_path in the probe name */
11886-
for (i = 0; buf[i]; i++) {
11887-
if (!isalnum(buf[i]))
11888-
buf[i] = '_';
11889-
}
11890-
}
11891-
1189211880
static inline int add_uprobe_event_legacy(const char *probe_name, bool retprobe,
1189311881
const char *binary_path, size_t offset)
1189411882
{
@@ -12312,13 +12300,14 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
1231212300
pfd = perf_event_open_probe(true /* uprobe */, retprobe, binary_path,
1231312301
func_offset, pid, ref_ctr_off);
1231412302
} else {
12315-
char probe_name[PATH_MAX + 64];
12303+
char probe_name[MAX_EVENT_NAME_LEN];
1231612304

1231712305
if (ref_ctr_off)
1231812306
return libbpf_err_ptr(-EINVAL);
1231912307

12320-
gen_uprobe_legacy_event_name(probe_name, sizeof(probe_name),
12321-
binary_path, func_offset);
12308+
gen_probe_legacy_event_name(probe_name, sizeof(probe_name),
12309+
strrchr(binary_path, '/') ? : binary_path,
12310+
func_offset);
1232212311

1232312312
legacy_probe = strdup(probe_name);
1232412313
if (!legacy_probe)

tools/testing/selftests/bpf/prog_tests/attach_probe.c

+84
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,85 @@ static void test_attach_probe_manual(enum probe_attach_mode attach_mode)
122122
test_attach_probe_manual__destroy(skel);
123123
}
124124

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+
125204
static void test_attach_probe_auto(struct test_attach_probe *skel)
126205
{
127206
struct bpf_link *uprobe_err_link;
@@ -323,6 +402,11 @@ void test_attach_probe(void)
323402
if (test__start_subtest("uprobe-ref_ctr"))
324403
test_uprobe_ref_ctr(skel);
325404

405+
if (test__start_subtest("uprobe-long_name"))
406+
test_attach_uprobe_long_event_name();
407+
if (test__start_subtest("kprobe-long_name"))
408+
test_attach_kprobe_long_event_name();
409+
326410
cleanup:
327411
test_attach_probe__destroy(skel);
328412
ASSERT_EQ(uprobe_ref_ctr, 0, "uprobe_ref_ctr_cleanup");

tools/testing/selftests/bpf/test_kmods/bpf_testmod.c

+4
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ bpf_testmod_test_arg_ptr_to_struct(struct bpf_testmod_struct_arg_1 *a) {
134134
return bpf_testmod_test_struct_arg_result;
135135
}
136136

137+
__weak noinline void bpf_testmod_looooooooooooooooooooooooooooooong_name(void)
138+
{
139+
}
140+
137141
__bpf_kfunc void
138142
bpf_testmod_test_mod_kfunc(int i)
139143
{

0 commit comments

Comments
 (0)