@@ -4990,20 +4990,22 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
4990
4990
struct bpf_reg_state *reg, u32 regno)
4991
4991
{
4992
4992
const char *targ_name = btf_type_name(kptr_field->kptr.btf, kptr_field->kptr.btf_id);
4993
- int perm_flags = PTR_MAYBE_NULL | PTR_TRUSTED | MEM_RCU ;
4993
+ int perm_flags;
4994
4994
const char *reg_name = "";
4995
4995
4996
- /* Only unreferenced case accepts untrusted pointers */
4997
- if (kptr_field->type == BPF_KPTR_UNREF)
4998
- perm_flags |= PTR_UNTRUSTED;
4996
+ if (btf_is_kernel(reg->btf)) {
4997
+ perm_flags = PTR_MAYBE_NULL | PTR_TRUSTED | MEM_RCU;
4998
+
4999
+ /* Only unreferenced case accepts untrusted pointers */
5000
+ if (kptr_field->type == BPF_KPTR_UNREF)
5001
+ perm_flags |= PTR_UNTRUSTED;
5002
+ } else {
5003
+ perm_flags = PTR_MAYBE_NULL | MEM_ALLOC;
5004
+ }
4999
5005
5000
5006
if (base_type(reg->type) != PTR_TO_BTF_ID || (type_flag(reg->type) & ~perm_flags))
5001
5007
goto bad_type;
5002
5008
5003
- if (!btf_is_kernel(reg->btf)) {
5004
- verbose(env, "R%d must point to kernel BTF\n", regno);
5005
- return -EINVAL;
5006
- }
5007
5009
/* We need to verify reg->type and reg->btf, before accessing reg->btf */
5008
5010
reg_name = btf_type_name(reg->btf, reg->btf_id);
5009
5011
@@ -5016,7 +5018,7 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
5016
5018
if (__check_ptr_off_reg(env, reg, regno, true))
5017
5019
return -EACCES;
5018
5020
5019
- /* A full type match is needed, as BTF can be vmlinux or module BTF, and
5021
+ /* A full type match is needed, as BTF can be vmlinux, module or prog BTF, and
5020
5022
* we also need to take into account the reg->off.
5021
5023
*
5022
5024
* We want to support cases like:
@@ -7916,7 +7918,10 @@ static int check_reg_type(struct bpf_verifier_env *env, u32 regno,
7916
7918
verbose(env, "verifier internal error: unimplemented handling of MEM_ALLOC\n");
7917
7919
return -EFAULT;
7918
7920
}
7919
- /* Handled by helper specific checks */
7921
+ if (meta->func_id == BPF_FUNC_kptr_xchg) {
7922
+ if (map_kptr_match_type(env, meta->kptr_field, reg, regno))
7923
+ return -EACCES;
7924
+ }
7920
7925
break;
7921
7926
case PTR_TO_BTF_ID | MEM_PERCPU:
7922
7927
case PTR_TO_BTF_ID | MEM_PERCPU | PTR_TRUSTED:
0 commit comments