Commit 57875408 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann
Browse files

selftests/bpf: Add tests to validate log_true_size feature



Add additional test cases validating that log_true_size is consistent
between fixed and rotating log modes, and that log_true_size can be
used *exactly* without causing -ENOSPC, while using just 1 byte shorter
log buffer would cause -ENOSPC.

Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarLorenz Bauer <lmb@isovalent.com>
Link: https://lore.kernel.org/bpf/20230406234205.323208-18-andrii@kernel.org
parent 097d8002
Loading
Loading
Loading
Loading
+76 −16
Original line number Diff line number Diff line
@@ -18,25 +18,41 @@ static bool check_prog_load(int prog_fd, bool expect_err, const char *tag)
		if (!ASSERT_GT(prog_fd, 0, tag))
			return false;
	}
	if (prog_fd >= 0)
		close(prog_fd);
	return true;
}

static void verif_log_subtest(const char *name, bool expect_load_error, int log_level)
{
	LIBBPF_OPTS(bpf_prog_load_opts, opts);
	struct {
static struct {
	/* strategically placed before others to avoid accidental modification by kernel */
	char filler[1024];
	char buf[1024];
	/* strategically placed after buf[] to catch more accidental corruptions */
	char reference[1024];
} logs;
static const struct bpf_insn *insns;
static size_t insn_cnt;

static int load_prog(struct bpf_prog_load_opts *opts, bool expect_load_error)
{
	int prog_fd;

	prog_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT, "log_prog",
				"GPL", insns, insn_cnt, opts);
	check_prog_load(prog_fd, expect_load_error, "prog_load");

	return prog_fd;
}

static void verif_log_subtest(const char *name, bool expect_load_error, int log_level)
{
	LIBBPF_OPTS(bpf_prog_load_opts, opts);
	char *exp_log, prog_name[16], op_name[32];
	struct test_log_buf *skel;
	struct bpf_program *prog;
	const struct bpf_insn *insns;
	size_t insn_cnt, fixed_log_sz;
	int i, mode, err, prog_fd;
	size_t fixed_log_sz;
	__u32 log_true_sz_fixed, log_true_sz_rolling;
	int i, mode, err, prog_fd, res;

	skel = test_log_buf__open();
	if (!ASSERT_OK_PTR(skel, "skel_open"))
@@ -61,11 +77,7 @@ static void verif_log_subtest(const char *name, bool expect_load_error, int log_
	opts.log_buf = logs.reference;
	opts.log_size = sizeof(logs.reference);
	opts.log_level = log_level | 8 /* BPF_LOG_FIXED */;
	prog_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT, "log_fixed",
				"GPL", insns, insn_cnt, &opts);
	if (!check_prog_load(prog_fd, expect_load_error, "fixed_buf_prog_load"))
		goto cleanup;
	close(prog_fd);
	load_prog(&opts, expect_load_error);

	fixed_log_sz = strlen(logs.reference) + 1;
	if (!ASSERT_GT(fixed_log_sz, 50, "fixed_log_sz"))
@@ -89,7 +101,7 @@ static void verif_log_subtest(const char *name, bool expect_load_error, int log_
		opts.log_level = log_level | 8; /* fixed-length log */
		opts.log_size = 25;

		prog_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT, "log_fixed50",
		prog_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT, "log_fixed25",
					"GPL", insns, insn_cnt, &opts);
		if (!ASSERT_EQ(prog_fd, -ENOSPC, "unexpected_log_fixed_prog_load_result")) {
			if (prog_fd >= 0)
@@ -162,6 +174,54 @@ static void verif_log_subtest(const char *name, bool expect_load_error, int log_
		}
	}

	/* (FIXED) get actual log size */
	opts.log_buf = logs.buf;
	opts.log_level = log_level | 8; /* BPF_LOG_FIXED */
	opts.log_size = sizeof(logs.buf);
	res = load_prog(&opts, expect_load_error);
	ASSERT_NEQ(res, -ENOSPC, "prog_load_res_fixed");

	log_true_sz_fixed = opts.log_true_size;
	ASSERT_GT(log_true_sz_fixed, 0, "log_true_sz_fixed");

	/* (ROLLING) get actual log size */
	opts.log_buf = logs.buf;
	opts.log_level = log_level;
	opts.log_size = sizeof(logs.buf);
	res = load_prog(&opts, expect_load_error);
	ASSERT_NEQ(res, -ENOSPC, "prog_load_res_rolling");

	log_true_sz_rolling = opts.log_true_size;
	ASSERT_EQ(log_true_sz_rolling, log_true_sz_fixed, "log_true_sz_eq");

	/* (FIXED) expect -ENOSPC for one byte short log */
	opts.log_buf = logs.buf;
	opts.log_level = log_level | 8; /* BPF_LOG_FIXED */
	opts.log_size = log_true_sz_fixed - 1;
	res = load_prog(&opts, true /* should fail */);
	ASSERT_EQ(res, -ENOSPC, "prog_load_res_too_short_fixed");

	/* (FIXED) expect *not* -ENOSPC with exact log_true_size buffer */
	opts.log_buf = logs.buf;
	opts.log_level = log_level | 8; /* BPF_LOG_FIXED */
	opts.log_size = log_true_sz_fixed;
	res = load_prog(&opts, expect_load_error);
	ASSERT_NEQ(res, -ENOSPC, "prog_load_res_just_right_fixed");

	/* (ROLLING) expect -ENOSPC for one byte short log */
	opts.log_buf = logs.buf;
	opts.log_level = log_level;
	opts.log_size = log_true_sz_rolling - 1;
	res = load_prog(&opts, true /* should fail */);
	ASSERT_EQ(res, -ENOSPC, "prog_load_res_too_short_rolling");

	/* (ROLLING) expect *not* -ENOSPC with exact log_true_size buffer */
	opts.log_buf = logs.buf;
	opts.log_level = log_level;
	opts.log_size = log_true_sz_rolling;
	res = load_prog(&opts, expect_load_error);
	ASSERT_NEQ(res, -ENOSPC, "prog_load_res_just_right_rolling");

cleanup:
	test_log_buf__destroy(skel);
}