Commit 2ca178f0 authored by Jiri Olsa's avatar Jiri Olsa Committed by Andrii Nakryiko
Browse files

libbpf: Add support for kprobe session attach



Adding support to attach program in kprobe session mode
with bpf_program__attach_kprobe_multi_opts function.

Adding session bool to bpf_kprobe_multi_opts struct that allows
to load and attach the bpf program via kprobe session.
the attachment to create kprobe multi session.

Also adding new program loader section that allows:
 SEC("kprobe.session/bpf_fentry_test*")

and loads/attaches kprobe program as kprobe session.

Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20240430112830.1184228-5-jolsa@kernel.org
parent 5c919ace
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -766,6 +766,7 @@ int bpf_link_create(int prog_fd, int target_fd,
			return libbpf_err(-EINVAL);
		break;
	case BPF_TRACE_KPROBE_MULTI:
	case BPF_TRACE_KPROBE_SESSION:
		attr.link_create.kprobe_multi.flags = OPTS_GET(opts, kprobe_multi.flags, 0);
		attr.link_create.kprobe_multi.cnt = OPTS_GET(opts, kprobe_multi.cnt, 0);
		attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0));
+37 −2
Original line number Diff line number Diff line
@@ -9273,6 +9273,7 @@ static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_lin
static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link);
static int attach_trace(const struct bpf_program *prog, long cookie, struct bpf_link **link);
static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
static int attach_kprobe_session(const struct bpf_program *prog, long cookie, struct bpf_link **link);
static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_link **link);
static int attach_iter(const struct bpf_program *prog, long cookie, struct bpf_link **link);
@@ -9289,6 +9290,7 @@ static const struct bpf_sec_def section_defs[] = {
	SEC_DEF("uretprobe.s+",		KPROBE, 0, SEC_SLEEPABLE, attach_uprobe),
	SEC_DEF("kprobe.multi+",	KPROBE,	BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
	SEC_DEF("kretprobe.multi+",	KPROBE,	BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
	SEC_DEF("kprobe.session+",	KPROBE,	BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session),
	SEC_DEF("uprobe.multi+",	KPROBE,	BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
	SEC_DEF("uretprobe.multi+",	KPROBE,	BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
	SEC_DEF("uprobe.multi.s+",	KPROBE,	BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi),
@@ -11381,13 +11383,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
	struct kprobe_multi_resolve res = {
		.pattern = pattern,
	};
	enum bpf_attach_type attach_type;
	struct bpf_link *link = NULL;
	char errmsg[STRERR_BUFSIZE];
	const unsigned long *addrs;
	int err, link_fd, prog_fd;
	bool retprobe, session;
	const __u64 *cookies;
	const char **syms;
	bool retprobe;
	size_t cnt;

	if (!OPTS_VALID(opts, bpf_kprobe_multi_opts))
@@ -11426,6 +11429,12 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
	}

	retprobe = OPTS_GET(opts, retprobe, false);
	session  = OPTS_GET(opts, session, false);

	if (retprobe && session)
		return libbpf_err_ptr(-EINVAL);

	attach_type = session ? BPF_TRACE_KPROBE_SESSION : BPF_TRACE_KPROBE_MULTI;

	lopts.kprobe_multi.syms = syms;
	lopts.kprobe_multi.addrs = addrs;
@@ -11440,7 +11449,7 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
	}
	link->detach = &bpf_link__detach_fd;

	link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, &lopts);
	link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);
	if (link_fd < 0) {
		err = -errno;
		pr_warn("prog '%s': failed to attach: %s\n",
@@ -11546,6 +11555,32 @@ static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, stru
	return libbpf_get_error(*link);
}

static int attach_kprobe_session(const struct bpf_program *prog, long cookie,
				 struct bpf_link **link)
{
	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts, .session = true);
	const char *spec;
	char *pattern;
	int n;

	*link = NULL;

	/* no auto-attach for SEC("kprobe.session") */
	if (strcmp(prog->sec_name, "kprobe.session") == 0)
		return 0;

	spec = prog->sec_name + sizeof("kprobe.session/") - 1;
	n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &pattern);
	if (n < 1) {
		pr_warn("kprobe session pattern is invalid: %s\n", pattern);
		return -EINVAL;
	}

	*link = bpf_program__attach_kprobe_multi_opts(prog, pattern, &opts);
	free(pattern);
	return *link ? 0 : -errno;
}

static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link)
{
	char *probe_type = NULL, *binary_path = NULL, *func_name = NULL;
+3 −1
Original line number Diff line number Diff line
@@ -539,10 +539,12 @@ struct bpf_kprobe_multi_opts {
	size_t cnt;
	/* create return kprobes */
	bool retprobe;
	/* create session kprobes */
	bool session;
	size_t :0;
};

#define bpf_kprobe_multi_opts__last_field retprobe
#define bpf_kprobe_multi_opts__last_field session

LIBBPF_API struct bpf_link *
bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,