Ensure that accessing a map aligns with an element if the corresponding btf_field, if there is, represents an array. Without this change, an access would need to align with the beginning of an array, otherwise it would be rejected. Signed-off-by: Kui-Feng Lee <thinker.li@xxxxxxxxx> --- kernel/bpf/verifier.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 86adacc5f76c..302aad33a7f4 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5426,7 +5426,7 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno, rec = map->record; for (i = 0; i < rec->cnt; i++) { struct btf_field *field = &rec->fields[i]; - u32 p = field->offset; + u32 p = field->offset, var_p, elem_size; /* If any part of a field can be touched by load/store, reject * this program. To check that [x1, x2) overlaps with [y1, y2), @@ -5446,7 +5446,10 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno, verbose(env, "kptr access cannot have variable offset\n"); return -EACCES; } - if (p != off + reg->var_off.value) { + var_p = off + reg->var_off.value; + elem_size = field->size / field->nelems; + if (var_p < p || var_p >= p + field->size || + (var_p - p) % elem_size) { verbose(env, "kptr access misaligned expected=%u off=%llu\n", p, off + reg->var_off.value); return -EACCES; -- 2.34.1