parisc: Check user signal stack trampoline is inside TASK_SIZE
Add some additional checks to ensure the signal stack is inside userspace bounds. Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
parent
ea4b3fca18
commit
3e4a1aff2a
|
@ -237,18 +237,22 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
usp = (regs->gr[30] & ~(0x01UL));
|
usp = (regs->gr[30] & ~(0x01UL));
|
||||||
|
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
if (is_compat_task()) {
|
if (is_compat_task()) {
|
||||||
/* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */
|
/* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */
|
||||||
usp = (compat_uint_t)usp;
|
usp = (compat_uint_t)usp;
|
||||||
|
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*FIXME: frame_size parameter is unused, remove it. */
|
frame = get_sigframe(&ksig->ka, usp, sigframe_size);
|
||||||
frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
|
|
||||||
|
|
||||||
DBG(1,"SETUP_RT_FRAME: START\n");
|
DBG(1,"SETUP_RT_FRAME: START\n");
|
||||||
DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
|
DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
|
||||||
|
|
||||||
|
start = (unsigned long) frame;
|
||||||
|
if (start >= user_addr_max() - sigframe_size)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
|
|
||||||
|
@ -343,11 +347,6 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
|
||||||
|
|
||||||
/* The syscall return path will create IAOQ values from r31.
|
/* The syscall return path will create IAOQ values from r31.
|
||||||
*/
|
*/
|
||||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
|
|
||||||
#ifdef CONFIG_64BIT
|
|
||||||
if (is_compat_task())
|
|
||||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
|
||||||
#endif
|
|
||||||
if (in_syscall) {
|
if (in_syscall) {
|
||||||
regs->gr[31] = haddr;
|
regs->gr[31] = haddr;
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
|
@ -518,6 +517,10 @@ insert_restart_trampoline(struct pt_regs *regs)
|
||||||
unsigned long end = (unsigned long) &usp[5];
|
unsigned long end = (unsigned long) &usp[5];
|
||||||
long err = 0;
|
long err = 0;
|
||||||
|
|
||||||
|
/* check that we don't exceed the stack */
|
||||||
|
if (A(&usp[0]) >= user_addr_max() - 5 * sizeof(int))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Setup a trampoline to restart the syscall
|
/* Setup a trampoline to restart the syscall
|
||||||
* with __NR_restart_syscall
|
* with __NR_restart_syscall
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue