NIOS2 fixes for v6.0
- Security fixes from Al Viro -----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEEoHhMeiyk5VmwVMwNGZQEC4GjKPQFAmL7rLwUHGRpbmd1eWVu QGtlcm5lbC5vcmcACgkQGZQEC4GjKPRkhg/+J7KxBV6cVBP1bIphiyWTN2Jwq1vm sEg676QtsQADs769I4zdvraebXj4dT7lFhPz8Pnmnyx6az+M0cIgyG5fFP0gHu2O +5KAca9XJRAuuPt/KtdnZK1VkL4NzMMAdFl8f4urZo717Qf2NzXg4+WDS27IWpLs eU8pMPre/uO51o1lwQfejUYL7HBCWbmjOMl4h0ioAMFeVF9R3w3YaUEodvSqI691 5ydXp1RwCGezRe2UkJRFGCnOOQ3J2+LNuhSVwXAkcaA0FAZRHEY7iiQZkbGDGLHO EJYb6QLeIu481rdpfBjDvTWSyieOoT6OpC8yIpkte4sodJvJgHDScHp5S318R3yD 05oxHuVoERMytCa8VRXRBFh+lpUvPJP/wVM+iwN232i81G+K1QsHeOs9Ow3/fxOo cmOv1Itrh1TC/v5W3xrranJNaI+Tpld2/Lh7RIdM6iDp6fEcYDIgaKECBBUUoAyn rd2QvOynM+pJ9Thp5GWwso4E96HtkMHcrHXahPljHkLBepZPBiwHfq2jk72FLlLI sLUDt5kE4/j2BvX4mL4U4kXNkXgpychxtNsCHO/IE/29em1ygPG/BoDbLDjnpBDC CZPw8YovPklEzL0qcq5OJT63RTCsbaaJBXnr0MRDJaFhKcaxwYVNRxOBcuijLYvp becGFNk43TNshJk= =HYlF -----END PGP SIGNATURE----- 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:
commit
3cc40a443a
@ -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 *);
|
|||||||
((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)
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
/* 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)
|
|||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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 @@
|
|||||||
#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>
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user