linux-user: Pass ka_restorer to do_sigaction
The value of ka_restorer needs to be saved in sigact_table. At the moment, the attempt to save it in do_syscall is improperly clobbering user memory. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20210422230227.314751-4-richard.henderson@linaro.org> [lv: remove tab] Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
parent
f20a9ca6d0
commit
02fb28e8ef
@ -842,7 +842,7 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr,
|
||||
|
||||
/* do_sigaction() return target values and host errnos */
|
||||
int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
struct target_sigaction *oact)
|
||||
struct target_sigaction *oact, abi_ulong ka_restorer)
|
||||
{
|
||||
struct target_sigaction *k;
|
||||
struct sigaction act1;
|
||||
@ -875,6 +875,9 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
__get_user(k->sa_flags, &act->sa_flags);
|
||||
#ifdef TARGET_ARCH_HAS_SA_RESTORER
|
||||
__get_user(k->sa_restorer, &act->sa_restorer);
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_HAS_KA_RESTORER
|
||||
k->ka_restorer = ka_restorer;
|
||||
#endif
|
||||
/* To be swapped in target_to_host_sigset. */
|
||||
k->sa_mask = act->sa_mask;
|
||||
|
@ -8989,11 +8989,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
act._sa_handler = old_act->_sa_handler;
|
||||
target_siginitset(&act.sa_mask, old_act->sa_mask);
|
||||
act.sa_flags = old_act->sa_flags;
|
||||
act.ka_restorer = 0;
|
||||
unlock_user_struct(old_act, arg2, 0);
|
||||
pact = &act;
|
||||
}
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact, 0));
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
|
||||
return -TARGET_EFAULT;
|
||||
@ -9017,7 +9016,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
pact = NULL;
|
||||
}
|
||||
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact, 0));
|
||||
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
|
||||
@ -9040,15 +9039,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
target_siginitset(&act.sa_mask, old_act->sa_mask);
|
||||
act.sa_flags = old_act->sa_flags;
|
||||
act.sa_restorer = old_act->sa_restorer;
|
||||
#ifdef TARGET_ARCH_HAS_KA_RESTORER
|
||||
act.ka_restorer = 0;
|
||||
#endif
|
||||
unlock_user_struct(old_act, arg2, 0);
|
||||
pact = &act;
|
||||
} else {
|
||||
pact = NULL;
|
||||
}
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact, 0));
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
|
||||
return -TARGET_EFAULT;
|
||||
@ -9085,11 +9081,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
act._sa_handler = rt_act->_sa_handler;
|
||||
act.sa_mask = rt_act->sa_mask;
|
||||
act.sa_flags = rt_act->sa_flags;
|
||||
act.ka_restorer = arg5;
|
||||
unlock_user_struct(rt_act, arg2, 0);
|
||||
pact = &act;
|
||||
}
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact, arg5));
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
|
||||
return -TARGET_EFAULT;
|
||||
@ -9104,6 +9099,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
target_ulong sigsetsize = arg5;
|
||||
#else
|
||||
target_ulong sigsetsize = arg4;
|
||||
target_ulong restorer = 0;
|
||||
#endif
|
||||
struct target_sigaction *act;
|
||||
struct target_sigaction *oact;
|
||||
@ -9115,9 +9111,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
#ifdef TARGET_ARCH_HAS_KA_RESTORER
|
||||
act->ka_restorer = restorer;
|
||||
#endif
|
||||
} else {
|
||||
act = NULL;
|
||||
}
|
||||
@ -9128,7 +9121,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
}
|
||||
} else
|
||||
oact = NULL;
|
||||
ret = get_errno(do_sigaction(arg1, act, oact));
|
||||
ret = get_errno(do_sigaction(arg1, act, oact, restorer));
|
||||
rt_sigaction_fail:
|
||||
if (act)
|
||||
unlock_user_struct(act, arg2, 0);
|
||||
|
@ -492,7 +492,7 @@ void target_to_host_old_sigset(sigset_t *sigset,
|
||||
const abi_ulong *old_sigset);
|
||||
struct target_sigaction;
|
||||
int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
struct target_sigaction *oact);
|
||||
struct target_sigaction *oact, abi_ulong ka_restorer);
|
||||
|
||||
#include "target_signal.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user