Ensure that accessing a map aligns with an element if the corresponding btf_field, if there is, represents an array. It would be necessary for an access to be aligned with the beginning of an array if we didn't make this change. Any access to elements other than the first one 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 34e43220c6f0..67b89d4ea1ba 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5428,7 +5428,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), @@ -5448,7 +5448,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