diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 2a69a9a36c0f..c08c44d62741 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -139,7 +139,7 @@ const struct bpf_func_proto bpf_map_lookup_percpu_elem_proto = { .pkt_access = true, .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL, .arg1_type = ARG_CONST_MAP_PTR, - .arg2_type = ARG_PTR_TO_MAP_KEY, + .arg2_type = ARG_PTR_TO_MAP_KEY | MEM_RDONLY, .arg3_type = ARG_ANYTHING, }; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 36ef8e96787e..021d50fa4702 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -7146,8 +7146,8 @@ static int check_stack_range_initialized( * reads. However, if raw_mode is not set, we'll do extra * checks below. */ - bounds_check_type = BPF_WRITE; - clobber = true; + clobber = !meta || meta->raw_mode; + bounds_check_type = clobber ? BPF_WRITE : BPF_READ; } else { bounds_check_type = BPF_READ; } @@ -7230,8 +7230,7 @@ static int check_stack_range_initialized( stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE]; if (*stype == STACK_MISC) goto mark; - if ((*stype == STACK_ZERO) || - (*stype == STACK_INVALID && env->allow_uninit_stack)) { + if (*stype == STACK_ZERO) { if (clobber) { /* helper can write anything into the stack */ *stype = STACK_MISC; @@ -8748,6 +8747,10 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, meta->map_uid = reg->map_uid; break; case ARG_PTR_TO_MAP_KEY: + /* mark read access for const* pointer type of fn argument to verify + * the pointed to value will be initialized for the call + */ + meta->raw_mode = !(arg_type & MEM_RDONLY); /* bpf_map_xxx(..., map_ptr, ..., key) call: * check that [key, key + map->key_size) are within * stack limits and initialized @@ -8763,7 +8766,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, } err = check_helper_mem_access(env, regno, meta->map_ptr->key_size, false, - NULL); + meta); break; case ARG_PTR_TO_MAP_VALUE: if (type_may_be_null(arg_type) && register_is_null(reg))