[PATCH] sh: reload r3 after arg evaluation in INTERNAL_SYSCALL [BZ #34167]

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Mon May 25 13:19:45 GMT 2026



On 23/05/26 17:18, Matt Turner wrote:
> r3 is caller-saved. When a function call appears in the args list
> (e.g. INTERNAL_SYSCALL_CALL(tgkill, __getpid(), tid, sig)),
> SUBSTITUTE_ARGS evaluates __getpid() before r3 is reloaded, leaving
> r3=20 (__NR_getpid) instead of __NR_tgkill=270. The trapa then
> dispatches the wrong syscall and the signal is silently dropped.
> 
> Fix: declare r3 uninitialised, expand SUBSTITUTE_ARGS (all function
> calls happen here), then assign the syscall number to r3 with no
> intervening calls before the trapa. Applies to both INTERNAL_SYSCALL
> and INTERNAL_SYSCALL_NCS.
> 
> signal/tst-raise is a regression test for this bug: raise() calls
> tgkill(__getpid(), tid, sig), which triggers the clobber.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>


> ---
>  sysdeps/unix/sysv/linux/sh/sysdep.h | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git ./sysdeps/unix/sysv/linux/sh/sysdep.h ./sysdeps/unix/sysv/linux/sh/sysdep.h
> index d51988e5b0..1562213bf6 100644
> --- ./sysdeps/unix/sysv/linux/sh/sysdep.h
> +++ ./sysdeps/unix/sysv/linux/sh/sysdep.h
> @@ -289,8 +289,9 @@
>  #define INTERNAL_SYSCALL(name, nr, args...) \
>    ({									      \
>      unsigned long int resultvar;					      \
> -    register long int r3 asm ("%r3") = SYS_ify (name);			      \
> +    register long int r3 asm ("%r3");					      \
>      SUBSTITUTE_ARGS_##nr(args);						      \
> +    r3 = SYS_ify (name);						      \
>  									      \
>      asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD			      \
>  		  : "=z" (resultvar)					      \
> @@ -303,8 +304,9 @@
>  #define INTERNAL_SYSCALL_NCS(name, nr, args...) \
>    ({									      \
>      unsigned long int resultvar;					      \
> -    register long int r3 asm ("%r3") = (name);				      \
> +    register long int r3 asm ("%r3");					      \
>      SUBSTITUTE_ARGS_##nr(args);						      \
> +    r3 = (name);							      \
>  									      \
>      asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD			      \
>  		  : "=z" (resultvar)					      \



More information about the Libc-alpha mailing list