Merge tag 'nios2_fixes_v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux
Pull NIOS2 fixes from Dinh Nguyen: - Security fixes from Al Viro * tag 'nios2_fixes_v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux: nios2: add force_successful_syscall_return() nios2: restarts apply only to the first sigframe we build... nios2: fix syscall restart checks nios2: traced syscall does need to check the syscall number nios2: don't leave NULLs in sys_call_table[] nios2: page fault et.al. are *not* restartable syscalls...
This commit is contained in:
@@ -50,7 +50,8 @@
|
||||
stw r13, PT_R13(sp)
|
||||
stw r14, PT_R14(sp)
|
||||
stw r15, PT_R15(sp)
|
||||
stw r2, PT_ORIG_R2(sp)
|
||||
movi r24, -1
|
||||
stw r24, PT_ORIG_R2(sp)
|
||||
stw r7, PT_ORIG_R7(sp)
|
||||
|
||||
stw ra, PT_RA(sp)
|
||||
|
@@ -74,6 +74,8 @@ extern void show_regs(struct pt_regs *);
|
||||
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE)\
|
||||
- 1)
|
||||
|
||||
#define force_successful_syscall_return() (current_pt_regs()->orig_r2 = -1)
|
||||
|
||||
int do_syscall_trace_enter(void);
|
||||
void do_syscall_trace_exit(void);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@@ -185,6 +185,7 @@ ENTRY(handle_system_call)
|
||||
ldw r5, PT_R5(sp)
|
||||
|
||||
local_restart:
|
||||
stw r2, PT_ORIG_R2(sp)
|
||||
/* Check that the requested system call is within limits */
|
||||
movui r1, __NR_syscalls
|
||||
bgeu r2, r1, ret_invsyscall
|
||||
@@ -192,7 +193,6 @@ local_restart:
|
||||
movhi r11, %hiadj(sys_call_table)
|
||||
add r1, r1, r11
|
||||
ldw r1, %lo(sys_call_table)(r1)
|
||||
beq r1, r0, ret_invsyscall
|
||||
|
||||
/* Check if we are being traced */
|
||||
GET_THREAD_INFO r11
|
||||
@@ -213,6 +213,9 @@ local_restart:
|
||||
translate_rc_and_ret:
|
||||
movi r1, 0
|
||||
bge r2, zero, 3f
|
||||
ldw r1, PT_ORIG_R2(sp)
|
||||
addi r1, r1, 1
|
||||
beq r1, zero, 3f
|
||||
sub r2, zero, r2
|
||||
movi r1, 1
|
||||
3:
|
||||
@@ -255,9 +258,9 @@ traced_system_call:
|
||||
ldw r6, PT_R6(sp)
|
||||
ldw r7, PT_R7(sp)
|
||||
|
||||
/* Fetch the syscall function, we don't need to check the boundaries
|
||||
* since this is already done.
|
||||
*/
|
||||
/* Fetch the syscall function. */
|
||||
movui r1, __NR_syscalls
|
||||
bgeu r2, r1, traced_invsyscall
|
||||
slli r1, r2, 2
|
||||
movhi r11,%hiadj(sys_call_table)
|
||||
add r1, r1, r11
|
||||
@@ -276,6 +279,9 @@ traced_system_call:
|
||||
translate_rc_and_ret2:
|
||||
movi r1, 0
|
||||
bge r2, zero, 4f
|
||||
ldw r1, PT_ORIG_R2(sp)
|
||||
addi r1, r1, 1
|
||||
beq r1, zero, 4f
|
||||
sub r2, zero, r2
|
||||
movi r1, 1
|
||||
4:
|
||||
@@ -287,6 +293,11 @@ end_translate_rc_and_ret2:
|
||||
RESTORE_SWITCH_STACK
|
||||
br ret_from_exception
|
||||
|
||||
/* If the syscall number was invalid return ENOSYS */
|
||||
traced_invsyscall:
|
||||
movi r2, -ENOSYS
|
||||
br translate_rc_and_ret2
|
||||
|
||||
Luser_return:
|
||||
GET_THREAD_INFO r11 /* get thread_info pointer */
|
||||
ldw r10, TI_FLAGS(r11) /* get thread_info->flags */
|
||||
@@ -336,9 +347,6 @@ external_interrupt:
|
||||
/* skip if no interrupt is pending */
|
||||
beq r12, r0, ret_from_interrupt
|
||||
|
||||
movi r24, -1
|
||||
stw r24, PT_ORIG_R2(sp)
|
||||
|
||||
/*
|
||||
* Process an external hardware interrupt.
|
||||
*/
|
||||
|
@@ -242,7 +242,7 @@ static int do_signal(struct pt_regs *regs)
|
||||
/*
|
||||
* If we were from a system call, check for system call restarting...
|
||||
*/
|
||||
if (regs->orig_r2 >= 0) {
|
||||
if (regs->orig_r2 >= 0 && regs->r1) {
|
||||
continue_addr = regs->ea;
|
||||
restart_addr = continue_addr - 4;
|
||||
retval = regs->r2;
|
||||
@@ -264,6 +264,7 @@ static int do_signal(struct pt_regs *regs)
|
||||
regs->ea = restart_addr;
|
||||
break;
|
||||
}
|
||||
regs->orig_r2 = -1;
|
||||
}
|
||||
|
||||
if (get_signal(&ksig)) {
|
||||
|
@@ -13,5 +13,6 @@
|
||||
#define __SYSCALL(nr, call) [nr] = (call),
|
||||
|
||||
void *sys_call_table[__NR_syscalls] = {
|
||||
[0 ... __NR_syscalls-1] = sys_ni_syscall,
|
||||
#include <asm/unistd.h>
|
||||
};
|
||||
|
Reference in New Issue
Block a user