Move the check for PTR_TO_MAP_VALUE to check_func_arg, where all other checking is done as well. Move the invocation of process_spin_lock away from the register type checking, to allow a future refactoring.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -3828,10 +3828,6 @@ static int process_spin_lock(struct bpf_verifier_env *env, int regno, · 3827 unmodified lines | ||
| 3828 | 3828 | struct bpf_map *map = reg->map_ptr; |
| 3829 | 3829 | u64 val = reg->var_off.value; |
| 3830 | 3830 | |
| 3831 | − if (reg->type != PTR_TO_MAP_VALUE) { | |
| 3832 | − verbose(env, "R%d is not a pointer to map_value\n", regno); | |
| 3833 | − return -EINVAL; | |
| 3834 | − } | |
| 3835 | 3831 | if (!is_const) { |
| 3836 | 3832 | verbose(env, |
| 3837 | 3833 | "R%d doesn't have constant offset. bpf_spin_lock has to be at the constant offset\n", |
| @@ -4040,16 +4036,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, · 202 unmodified lines | ||
| 4040 | 4036 | if (type != expected_type) |
| 4041 | 4037 | goto err_type; |
| 4042 | 4038 | } else if (arg_type == ARG_PTR_TO_SPIN_LOCK) { |
| 4043 | − if (meta->func_id == BPF_FUNC_spin_lock) { | |
| 4044 | − if (process_spin_lock(env, regno, true)) | |
| 4045 | − return -EACCES; | |
| 4046 | − } else if (meta->func_id == BPF_FUNC_spin_unlock) { | |
| 4047 | − if (process_spin_lock(env, regno, false)) | |
| 4048 | − return -EACCES; | |
| 4049 | − } else { | |
| 4050 | − verbose(env, "verifier internal error\n"); | |
| 4051 | − return -EFAULT; | |
| 4052 | − } | |
| 4039 | + expected_type = PTR_TO_MAP_VALUE; | |
| 4040 | + if (type != expected_type) | |
| 4041 | + goto err_type; | |
| 4053 | 4042 | } else if (arg_type_is_mem_ptr(arg_type)) { |
| 4054 | 4043 | expected_type = PTR_TO_STACK; |
| 4055 | 4044 | /* One exception here. In case function allows for NULL to be |
| @@ -4155,6 +4144,17 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, · 99 unmodified lines | ||
| 4155 | 4144 | err = check_helper_mem_access(env, regno, |
| 4156 | 4145 | meta->map_ptr->value_size, false, |
| 4157 | 4146 | meta); |
| 4147 | + } else if (arg_type == ARG_PTR_TO_SPIN_LOCK) { | |
| 4148 | + if (meta->func_id == BPF_FUNC_spin_lock) { | |
| 4149 | + if (process_spin_lock(env, regno, true)) | |
| 4150 | + return -EACCES; | |
| 4151 | + } else if (meta->func_id == BPF_FUNC_spin_unlock) { | |
| 4152 | + if (process_spin_lock(env, regno, false)) | |
| 4153 | + return -EACCES; | |
| 4154 | + } else { | |
| 4155 | + verbose(env, "verifier internal error\n"); | |
| 4156 | + return -EFAULT; | |
| 4157 | + } | |
| 4158 | 4158 | } else if (arg_type_is_mem_ptr(arg_type)) { |
| 4159 | 4159 | /* The access to this pointer is only checked when we hit the |
| 4160 | 4160 | * next is_mem_size argument below. |