mirror of
https://github.com/torvalds/linux.git
synced 2026-10-26 20:46:02 +01:00
powerpc/signal64: use scoped user access in setup_trampoline()
setup_trampoline() writes the seven words of the on-stack sigreturn trampoline with __put_user(), relying on the frame having been checked when the frame setup opened its user write access. It is called after that access has been closed again, so each of the seven writes opens and closes user access on its own. Write them inside one scoped_user_write_access_size() covering the whole trampoline instead. Everything in it is a store, so a write-only window is enough, and the instruction cache flush stays outside it. This is part of getting rid of __get_user() and __put_user() entirely. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
2f0bb47c00
commit
52907f0e47
|
|
@ -624,24 +624,27 @@ static long restore_tm_sigcontexts(struct task_struct *tsk, struct sigcontext __
|
|||
static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
|
||||
{
|
||||
int i;
|
||||
long err = 0;
|
||||
|
||||
/* Call the handler and pop the dummy stackframe*/
|
||||
err |= __put_user(PPC_RAW_BCTRL(), &tramp[0]);
|
||||
err |= __put_user(PPC_RAW_ADDI(_R1, _R1, __SIGNAL_FRAMESIZE), &tramp[1]);
|
||||
scoped_user_write_access_size(tramp, TRAMP_SIZE * sizeof(*tramp), efault) {
|
||||
/* Call the handler and pop the dummy stackframe*/
|
||||
unsafe_put_user(PPC_RAW_BCTRL(), &tramp[0], efault);
|
||||
unsafe_put_user(PPC_RAW_ADDI(_R1, _R1, __SIGNAL_FRAMESIZE), &tramp[1], efault);
|
||||
|
||||
err |= __put_user(PPC_RAW_LI(_R0, syscall), &tramp[2]);
|
||||
err |= __put_user(PPC_RAW_SC(), &tramp[3]);
|
||||
unsafe_put_user(PPC_RAW_LI(_R0, syscall), &tramp[2], efault);
|
||||
unsafe_put_user(PPC_RAW_SC(), &tramp[3], efault);
|
||||
|
||||
/* Minimal traceback info */
|
||||
for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
|
||||
err |= __put_user(0, &tramp[i]);
|
||||
/* Minimal traceback info */
|
||||
for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
|
||||
unsafe_put_user(0, &tramp[i], efault);
|
||||
}
|
||||
|
||||
if (!err)
|
||||
flush_icache_range((unsigned long) &tramp[0],
|
||||
flush_icache_range((unsigned long) &tramp[0],
|
||||
(unsigned long) &tramp[TRAMP_SIZE]);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
|
||||
efault:
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user