Skip to content

Commit c3416c9

Browse files
committed
bpf: Check PTR_TO_MEM | MEM_RDONLY in check_helper_mem_access
jira VULN-136 cve CVE-2022-0500 commit-author Kumar Kartikeya Dwivedi <[email protected]> commit 97e6d7d The commit being fixed was aiming to disallow users from incorrectly obtaining writable pointer to memory that is only meant to be read. This is enforced now using a MEM_RDONLY flag. For instance, in case of global percpu variables, when the BTF type is not struct (e.g. bpf_prog_active), the verifier marks register type as PTR_TO_MEM | MEM_RDONLY from bpf_this_cpu_ptr or bpf_per_cpu_ptr helpers. However, when passing such pointer to kfunc, global funcs, or BPF helpers, in check_helper_mem_access, there is no expectation MEM_RDONLY flag will be set, hence it is checked as pointer to writable memory. Later, verifier sets up argument type of global func as PTR_TO_MEM | PTR_MAYBE_NULL, so user can use a global func to get around the limitations imposed by this flag. This check will also cover global non-percpu variables that may be introduced in kernel BTF in future. Also, we update the log message for PTR_TO_BUF case to be similar to PTR_TO_MEM case, so that the reason for error is clear to user. Fixes: 34d3a78 ("bpf: Make per_cpu_ptr return rdonly PTR_TO_MEM.") Reviewed-by: Hao Luo <[email protected]> Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]> (cherry picked from commit 97e6d7d) Signed-off-by: Brett Mastbergen <[email protected]>
1 parent 007ca93 commit c3416c9

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

kernel/bpf/verifier.c

+11-1
Original file line numberDiff line numberDiff line change
@@ -4496,13 +4496,23 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
44964496
return check_map_access(env, regno, reg->off, access_size,
44974497
zero_size_allowed);
44984498
case PTR_TO_MEM:
4499+
if (type_is_rdonly_mem(reg->type)) {
4500+
if (meta && meta->raw_mode) {
4501+
verbose(env, "R%d cannot write into %s\n", regno,
4502+
reg_type_str(env, reg->type));
4503+
return -EACCES;
4504+
}
4505+
}
44994506
return check_mem_region_access(env, regno, reg->off,
45004507
access_size, reg->mem_size,
45014508
zero_size_allowed);
45024509
case PTR_TO_BUF:
45034510
if (type_is_rdonly_mem(reg->type)) {
4504-
if (meta && meta->raw_mode)
4511+
if (meta && meta->raw_mode) {
4512+
verbose(env, "R%d cannot write into %s\n", regno,
4513+
reg_type_str(env, reg->type));
45054514
return -EACCES;
4515+
}
45064516

45074517
buf_info = "rdonly";
45084518
max_access = &env->prog->aux->max_rdonly_access;

0 commit comments

Comments
 (0)