Commit 310794c2 authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

Merge branch 'bpf-some-fixes-for-nullness-elision'

Daniel Xu says:

====================
Tow fixes for nullness elision.

Changes from v1:
* Reword commit message in patch 1
* Add tags
====================

Link: https://patch.msgid.link/cover.1738689872.git.dxu@dxuuu.xyz


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 517e8a78 7968c658
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -9149,10 +9149,11 @@ static int check_reg_const_str(struct bpf_verifier_env *env,
	return 0;
}
/* Returns constant key value if possible, else negative error */
static s64 get_constant_map_key(struct bpf_verifier_env *env,
/* Returns constant key value in `value` if possible, else negative error */
static int get_constant_map_key(struct bpf_verifier_env *env,
				struct bpf_reg_state *key,
				u32 key_size)
				u32 key_size,
				s64 *value)
{
	struct bpf_func_state *state = func(env, key);
	struct bpf_reg_state *reg;
@@ -9179,8 +9180,10 @@ static s64 get_constant_map_key(struct bpf_verifier_env *env,
	/* First handle precisely tracked STACK_ZERO */
	for (i = off; i >= 0 && stype[i] == STACK_ZERO; i--)
		zero_size++;
	if (zero_size >= key_size)
	if (zero_size >= key_size) {
		*value = 0;
		return 0;
	}
	/* Check that stack contains a scalar spill of expected size */
	if (!is_spilled_scalar_reg(&state->stack[spi]))
@@ -9203,9 +9206,12 @@ static s64 get_constant_map_key(struct bpf_verifier_env *env,
	if (err < 0)
		return err;
	return reg->var_off.value;
	*value = reg->var_off.value;
	return 0;
}
static bool can_elide_value_nullness(enum bpf_map_type type);
static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
			  struct bpf_call_arg_meta *meta,
			  const struct bpf_func_proto *fn,
@@ -9354,9 +9360,16 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
		err = check_helper_mem_access(env, regno, key_size, BPF_READ, false, NULL);
		if (err)
			return err;
		meta->const_map_key = get_constant_map_key(env, reg, key_size);
		if (meta->const_map_key < 0 && meta->const_map_key != -EOPNOTSUPP)
			return meta->const_map_key;
		if (can_elide_value_nullness(meta->map_ptr->map_type)) {
			err = get_constant_map_key(env, reg, key_size, &meta->const_map_key);
			if (err < 0) {
				meta->const_map_key = -1;
				if (err == -EOPNOTSUPP)
					err = 0;
				else
					return err;
			}
		}
		break;
	case ARG_PTR_TO_MAP_VALUE:
		if (type_may_be_null(arg_type) && register_is_null(reg))
+15 −0
Original line number Diff line number Diff line
@@ -713,4 +713,19 @@ unsigned int non_stack_key_lookup(void)
	return val->index;
}

SEC("socket")
__description("doesn't reject UINT64_MAX as s64 for irrelevant maps")
__success __retval(42)
unsigned int doesnt_reject_irrelevant_maps(void)
{
	__u64 key = 0xFFFFFFFFFFFFFFFF;
	struct test_val *val;

	val = bpf_map_lookup_elem(&map_hash_48b, &key);
	if (val)
		return val->index;

	return 42;
}

char _license[] SEC("license") = "GPL";