Commit 3cc40a44 authored by Linus Torvalds's avatar Linus Torvalds

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...
parents 339800d5 fd0c153d
...@@ -50,7 +50,8 @@ ...@@ -50,7 +50,8 @@
stw r13, PT_R13(sp) stw r13, PT_R13(sp)
stw r14, PT_R14(sp) stw r14, PT_R14(sp)
stw r15, PT_R15(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 r7, PT_ORIG_R7(sp)
stw ra, PT_RA(sp) stw ra, PT_RA(sp)
......
...@@ -74,6 +74,8 @@ extern void show_regs(struct pt_regs *); ...@@ -74,6 +74,8 @@ extern void show_regs(struct pt_regs *);
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE)\ ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE)\
- 1) - 1)
#define force_successful_syscall_return() (current_pt_regs()->orig_r2 = -1)
int do_syscall_trace_enter(void); int do_syscall_trace_enter(void);
void do_syscall_trace_exit(void); void do_syscall_trace_exit(void);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
......
...@@ -185,6 +185,7 @@ ENTRY(handle_system_call) ...@@ -185,6 +185,7 @@ ENTRY(handle_system_call)
ldw r5, PT_R5(sp) ldw r5, PT_R5(sp)
local_restart: local_restart:
stw r2, PT_ORIG_R2(sp)
/* Check that the requested system call is within limits */ /* Check that the requested system call is within limits */
movui r1, __NR_syscalls movui r1, __NR_syscalls
bgeu r2, r1, ret_invsyscall bgeu r2, r1, ret_invsyscall
...@@ -192,7 +193,6 @@ local_restart: ...@@ -192,7 +193,6 @@ local_restart:
movhi r11, %hiadj(sys_call_table) movhi r11, %hiadj(sys_call_table)
add r1, r1, r11 add r1, r1, r11
ldw r1, %lo(sys_call_table)(r1) ldw r1, %lo(sys_call_table)(r1)
beq r1, r0, ret_invsyscall
/* Check if we are being traced */ /* Check if we are being traced */
GET_THREAD_INFO r11 GET_THREAD_INFO r11
...@@ -213,6 +213,9 @@ local_restart: ...@@ -213,6 +213,9 @@ local_restart:
translate_rc_and_ret: translate_rc_and_ret:
movi r1, 0 movi r1, 0
bge r2, zero, 3f bge r2, zero, 3f
ldw r1, PT_ORIG_R2(sp)
addi r1, r1, 1
beq r1, zero, 3f
sub r2, zero, r2 sub r2, zero, r2
movi r1, 1 movi r1, 1
3: 3:
...@@ -255,9 +258,9 @@ traced_system_call: ...@@ -255,9 +258,9 @@ traced_system_call:
ldw r6, PT_R6(sp) ldw r6, PT_R6(sp)
ldw r7, PT_R7(sp) ldw r7, PT_R7(sp)
/* Fetch the syscall function, we don't need to check the boundaries /* Fetch the syscall function. */
* since this is already done. movui r1, __NR_syscalls
*/ bgeu r2, r1, traced_invsyscall
slli r1, r2, 2 slli r1, r2, 2
movhi r11,%hiadj(sys_call_table) movhi r11,%hiadj(sys_call_table)
add r1, r1, r11 add r1, r1, r11
...@@ -276,6 +279,9 @@ traced_system_call: ...@@ -276,6 +279,9 @@ traced_system_call:
translate_rc_and_ret2: translate_rc_and_ret2:
movi r1, 0 movi r1, 0
bge r2, zero, 4f bge r2, zero, 4f
ldw r1, PT_ORIG_R2(sp)
addi r1, r1, 1
beq r1, zero, 4f
sub r2, zero, r2 sub r2, zero, r2
movi r1, 1 movi r1, 1
4: 4:
...@@ -287,6 +293,11 @@ end_translate_rc_and_ret2: ...@@ -287,6 +293,11 @@ end_translate_rc_and_ret2:
RESTORE_SWITCH_STACK RESTORE_SWITCH_STACK
br ret_from_exception br ret_from_exception
/* If the syscall number was invalid return ENOSYS */
traced_invsyscall:
movi r2, -ENOSYS
br translate_rc_and_ret2
Luser_return: Luser_return:
GET_THREAD_INFO r11 /* get thread_info pointer */ GET_THREAD_INFO r11 /* get thread_info pointer */
ldw r10, TI_FLAGS(r11) /* get thread_info->flags */ ldw r10, TI_FLAGS(r11) /* get thread_info->flags */
...@@ -336,9 +347,6 @@ external_interrupt: ...@@ -336,9 +347,6 @@ external_interrupt:
/* skip if no interrupt is pending */ /* skip if no interrupt is pending */
beq r12, r0, ret_from_interrupt beq r12, r0, ret_from_interrupt
movi r24, -1
stw r24, PT_ORIG_R2(sp)
/* /*
* Process an external hardware interrupt. * Process an external hardware interrupt.
*/ */
......
...@@ -242,7 +242,7 @@ static int do_signal(struct pt_regs *regs) ...@@ -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 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; continue_addr = regs->ea;
restart_addr = continue_addr - 4; restart_addr = continue_addr - 4;
retval = regs->r2; retval = regs->r2;
...@@ -264,6 +264,7 @@ static int do_signal(struct pt_regs *regs) ...@@ -264,6 +264,7 @@ static int do_signal(struct pt_regs *regs)
regs->ea = restart_addr; regs->ea = restart_addr;
break; break;
} }
regs->orig_r2 = -1;
} }
if (get_signal(&ksig)) { if (get_signal(&ksig)) {
......
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
#define __SYSCALL(nr, call) [nr] = (call), #define __SYSCALL(nr, call) [nr] = (call),
void *sys_call_table[__NR_syscalls] = { void *sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls-1] = sys_ni_syscall,
#include <asm/unistd.h> #include <asm/unistd.h>
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment