Commit 59bb14bd authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Daniel Borkmann says:

====================
pull-request: bpf 2023-06-21

We've added 7 non-merge commits during the last 14 day(s) which contain
a total of 7 files changed, 181 insertions(+), 15 deletions(-).

The main changes are:

1) Fix a verifier id tracking issue with scalars upon spill,
   from Maxim Mikityanskiy.

2) Fix NULL dereference if an exception is generated while a BPF
   subprogram is running, from Krister Johansen.

3) Fix a BTF verification failure when compiling kernel with LLVM_IAS=0,
   from Florent Revest.

4) Fix expected_attach_type enforcement for kprobe_multi link,
   from Jiri Olsa.

5) Fix a bpf_jit_dump issue for x86_64 to pick the correct JITed image,
   from Yonghong Song.

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
  bpf: Force kprobe multi expected_attach_type for kprobe_multi link
  bpf/btf: Accept function names that contain dots
  selftests/bpf: add a test for subprogram extables
  bpf: ensure main program has an extable
  bpf: Fix a bpf_jit_dump issue for x86_64 with sysctl bpf_jit_enable.
  selftests/bpf: Add test cases to assert proper ID tracking on spill
  bpf: Fix verifier id tracking of scalars on spill
====================

Link: https://lore.kernel.org/r/20230621101116.16122-1-daniel@iogearbox.net


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a129b41f db8eae6b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2570,7 +2570,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
	}

	if (bpf_jit_enable > 1)
		bpf_jit_dump(prog->len, proglen, pass + 1, image);
		bpf_jit_dump(prog->len, proglen, pass + 1, rw_image);

	if (image) {
		if (!prog->is_func || extra_pass) {
+8 −12
Original line number Diff line number Diff line
@@ -744,13 +744,12 @@ static bool btf_name_offset_valid(const struct btf *btf, u32 offset)
	return offset < btf->hdr.str_len;
}

static bool __btf_name_char_ok(char c, bool first, bool dot_ok)
static bool __btf_name_char_ok(char c, bool first)
{
	if ((first ? !isalpha(c) :
		     !isalnum(c)) &&
	    c != '_' &&
	    ((c == '.' && !dot_ok) ||
	      c != '.'))
	    c != '.')
		return false;
	return true;
}
@@ -767,20 +766,20 @@ static const char *btf_str_by_offset(const struct btf *btf, u32 offset)
	return NULL;
}

static bool __btf_name_valid(const struct btf *btf, u32 offset, bool dot_ok)
static bool __btf_name_valid(const struct btf *btf, u32 offset)
{
	/* offset must be valid */
	const char *src = btf_str_by_offset(btf, offset);
	const char *src_limit;

	if (!__btf_name_char_ok(*src, true, dot_ok))
	if (!__btf_name_char_ok(*src, true))
		return false;

	/* set a limit on identifier length */
	src_limit = src + KSYM_NAME_LEN;
	src++;
	while (*src && src < src_limit) {
		if (!__btf_name_char_ok(*src, false, dot_ok))
		if (!__btf_name_char_ok(*src, false))
			return false;
		src++;
	}
@@ -788,17 +787,14 @@ static bool __btf_name_valid(const struct btf *btf, u32 offset, bool dot_ok)
	return !*src;
}

/* Only C-style identifier is permitted. This can be relaxed if
 * necessary.
 */
static bool btf_name_valid_identifier(const struct btf *btf, u32 offset)
{
	return __btf_name_valid(btf, offset, false);
	return __btf_name_valid(btf, offset);
}

static bool btf_name_valid_section(const struct btf *btf, u32 offset)
{
	return __btf_name_valid(btf, offset, true);
	return __btf_name_valid(btf, offset);
}

static const char *__btf_name_by_offset(const struct btf *btf, u32 offset)
@@ -4422,7 +4418,7 @@ static s32 btf_var_check_meta(struct btf_verifier_env *env,
	}

	if (!t->name_off ||
	    !__btf_name_valid(env->btf, t->name_off, true)) {
	    !__btf_name_valid(env->btf, t->name_off)) {
		btf_verifier_log_type(env, t, "Invalid name");
		return -EINVAL;
	}
+5 −0
Original line number Diff line number Diff line
@@ -3440,6 +3440,11 @@ static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
		return prog->enforce_expected_attach_type &&
			prog->expected_attach_type != attach_type ?
			-EINVAL : 0;
	case BPF_PROG_TYPE_KPROBE:
		if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
		    attach_type != BPF_TRACE_KPROBE_MULTI)
			return -EINVAL;
		return 0;
	default:
		return 0;
	}
+8 −2
Original line number Diff line number Diff line
@@ -3868,6 +3868,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
				return err;
		}
		save_register_state(state, spi, reg, size);
		/* Break the relation on a narrowing spill. */
		if (fls64(reg->umax_value) > BITS_PER_BYTE * size)
			state->stack[spi].spilled_ptr.id = 0;
	} else if (!reg && !(off % BPF_REG_SIZE) && is_bpf_st_mem(insn) &&
		   insn->imm != 0 && env->bpf_capable) {
		struct bpf_reg_state fake_reg = {};
@@ -17214,9 +17217,10 @@ static int jit_subprogs(struct bpf_verifier_env *env)
	}
	/* finally lock prog and jit images for all functions and
	 * populate kallsysm
	 * populate kallsysm. Begin at the first subprogram, since
	 * bpf_prog_load will add the kallsyms for the main program.
	 */
	for (i = 0; i < env->subprog_cnt; i++) {
	for (i = 1; i < env->subprog_cnt; i++) {
		bpf_prog_lock_ro(func[i]);
		bpf_prog_kallsyms_add(func[i]);
	}
@@ -17242,6 +17246,8 @@ static int jit_subprogs(struct bpf_verifier_env *env)
	prog->jited = 1;
	prog->bpf_func = func[0]->bpf_func;
	prog->jited_len = func[0]->jited_len;
	prog->aux->extable = func[0]->aux->extable;
	prog->aux->num_exentries = func[0]->aux->num_exentries;
	prog->aux->func = func;
	prog->aux->func_cnt = env->subprog_cnt;
	bpf_prog_jit_attempt_done(prog);
+29 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <test_progs.h>
#include "test_subprogs_extable.skel.h"

void test_subprogs_extable(void)
{
	const int read_sz = 456;
	struct test_subprogs_extable *skel;
	int err;

	skel = test_subprogs_extable__open_and_load();
	if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
		return;

	err = test_subprogs_extable__attach(skel);
	if (!ASSERT_OK(err, "skel_attach"))
		goto cleanup;

	/* trigger tracepoint */
	ASSERT_OK(trigger_module_test_read(read_sz), "trigger_read");

	ASSERT_NEQ(skel->bss->triggered, 0, "verify at least one program ran");

	test_subprogs_extable__detach(skel);

cleanup:
	test_subprogs_extable__destroy(skel);
}
Loading