Skip to content

Commit 3cc40a4

Browse files
committed
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...
2 parents 339800d + fd0c153 commit 3cc40a4

5 files changed

Lines changed: 22 additions & 9 deletions

File tree

arch/nios2/include/asm/entry.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
stw r13, PT_R13(sp)
5151
stw r14, PT_R14(sp)
5252
stw r15, PT_R15(sp)
53-
stw r2, PT_ORIG_R2(sp)
53+
movi r24, -1
54+
stw r24, PT_ORIG_R2(sp)
5455
stw r7, PT_ORIG_R7(sp)
5556

5657
stw ra, PT_RA(sp)

arch/nios2/include/asm/ptrace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ extern void show_regs(struct pt_regs *);
7474
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE)\
7575
- 1)
7676

77+
#define force_successful_syscall_return() (current_pt_regs()->orig_r2 = -1)
78+
7779
int do_syscall_trace_enter(void);
7880
void do_syscall_trace_exit(void);
7981
#endif /* __ASSEMBLY__ */

arch/nios2/kernel/entry.S

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -185,14 +185,14 @@ ENTRY(handle_system_call)
185185
ldw r5, PT_R5(sp)
186186

187187
local_restart:
188+
stw r2, PT_ORIG_R2(sp)
188189
/* Check that the requested system call is within limits */
189190
movui r1, __NR_syscalls
190191
bgeu r2, r1, ret_invsyscall
191192
slli r1, r2, 2
192193
movhi r11, %hiadj(sys_call_table)
193194
add r1, r1, r11
194195
ldw r1, %lo(sys_call_table)(r1)
195-
beq r1, r0, ret_invsyscall
196196

197197
/* Check if we are being traced */
198198
GET_THREAD_INFO r11
@@ -213,6 +213,9 @@ local_restart:
213213
translate_rc_and_ret:
214214
movi r1, 0
215215
bge r2, zero, 3f
216+
ldw r1, PT_ORIG_R2(sp)
217+
addi r1, r1, 1
218+
beq r1, zero, 3f
216219
sub r2, zero, r2
217220
movi r1, 1
218221
3:
@@ -255,9 +258,9 @@ traced_system_call:
255258
ldw r6, PT_R6(sp)
256259
ldw r7, PT_R7(sp)
257260

258-
/* Fetch the syscall function, we don't need to check the boundaries
259-
* since this is already done.
260-
*/
261+
/* Fetch the syscall function. */
262+
movui r1, __NR_syscalls
263+
bgeu r2, r1, traced_invsyscall
261264
slli r1, r2, 2
262265
movhi r11,%hiadj(sys_call_table)
263266
add r1, r1, r11
@@ -276,6 +279,9 @@ traced_system_call:
276279
translate_rc_and_ret2:
277280
movi r1, 0
278281
bge r2, zero, 4f
282+
ldw r1, PT_ORIG_R2(sp)
283+
addi r1, r1, 1
284+
beq r1, zero, 4f
279285
sub r2, zero, r2
280286
movi r1, 1
281287
4:
@@ -287,6 +293,11 @@ end_translate_rc_and_ret2:
287293
RESTORE_SWITCH_STACK
288294
br ret_from_exception
289295

296+
/* If the syscall number was invalid return ENOSYS */
297+
traced_invsyscall:
298+
movi r2, -ENOSYS
299+
br translate_rc_and_ret2
300+
290301
Luser_return:
291302
GET_THREAD_INFO r11 /* get thread_info pointer */
292303
ldw r10, TI_FLAGS(r11) /* get thread_info->flags */
@@ -336,9 +347,6 @@ external_interrupt:
336347
/* skip if no interrupt is pending */
337348
beq r12, r0, ret_from_interrupt
338349

339-
movi r24, -1
340-
stw r24, PT_ORIG_R2(sp)
341-
342350
/*
343351
* Process an external hardware interrupt.
344352
*/

arch/nios2/kernel/signal.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ static int do_signal(struct pt_regs *regs)
242242
/*
243243
* If we were from a system call, check for system call restarting...
244244
*/
245-
if (regs->orig_r2 >= 0) {
245+
if (regs->orig_r2 >= 0 && regs->r1) {
246246
continue_addr = regs->ea;
247247
restart_addr = continue_addr - 4;
248248
retval = regs->r2;
@@ -264,6 +264,7 @@ static int do_signal(struct pt_regs *regs)
264264
regs->ea = restart_addr;
265265
break;
266266
}
267+
regs->orig_r2 = -1;
267268
}
268269

269270
if (get_signal(&ksig)) {

arch/nios2/kernel/syscall_table.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
#define __SYSCALL(nr, call) [nr] = (call),
1414

1515
void *sys_call_table[__NR_syscalls] = {
16+
[0 ... __NR_syscalls-1] = sys_ni_syscall,
1617
#include <asm/unistd.h>
1718
};

0 commit comments

Comments
 (0)