On 7/6/2026 9:51 AM, Ilya Leoshkevich wrote:
> page_check_range() may race with pageflags_set_clear() as follows:
>
> T1 T2
> ------------------------------------- --------------------------------
> p = pageflags_find(start, last);
> interval_tree_remove(&p->itree, ...);
> p->itree.start = last + 1;
> if (start < p->itree.start) {
> ret = false;
> interval_tree_insert(&p->itree, ...);
>
> leading to errors like
>
> fail indirect write 0x72f0a659aff0 (Bad address)
>
> in vma-pthread test. I am able to reliably reproduce this on a machine
> with 32 SMT threads as follows in about 25 seconds:
>
> jobs=32; \
> seq "$jobs" | \
> time -p parallel \
> --jobs="$jobs" \
> --halt=now,done=1 \
> --ungroup \
> '
> _={};
> while ./qemu-s390x tests/tcg/s390x-linux-user/vma-pthread; do
> printf .;
> done
> '
>
> Also wasmtime project reported a similar failure pattern in their CI [1]
> with a similar reproducer [2].
>
> There are other races like this. In general, region bounds mutating
> underneath the reader are very hard to reason about. So fix this by
> preventing mutations and creating copies instead. Use RCU guards in
> readers to avoid uses-after-frees.
>
> Now, when the reader finds a node, it may fearlessly access its fields
> and be certain that at some point in time the respective region had the
> respective bounds and permissions. The downside is slightly more
> expensive mprotect(), but complexity reduction is worth it.
>
> Lockless field accesses should probably be wrapped in qatomic_read(),
> but this is a pre-existing issue, so do not change it here.
>
> [1] https://github.com/bytecodealliance/wasmtime/issues/10000
> [2] https://gist.github.com/alexcrichton/f14f23a892ffb9df2522754572d51b1c
>
> Signed-off-by: Ilya Leoshkevich <[email protected]>
> ---
> accel/tcg/user-exec.c | 37 +++++++++++++++++++++----------------
> 1 file changed, 21 insertions(+), 16 deletions(-)
>
Reviewed-by: Pierrick Bouvier <[email protected]>