Skip to content

Commit 4370b67

Browse files
FlyGoattsbogend
authored andcommitted
MIPS: scall: Save thread_info.syscall unconditionally on entry
thread_info.syscall is used by syscall_get_nr to supply syscall nr over a thread stack frame. Previously, thread_info.syscall is only saved at syscall_trace_enter when syscall tracing is enabled. However rest of the kernel code do expect syscall_get_nr to be available without syscall tracing. The previous design breaks collect_syscall. Move saving process to syscall entry to fix it. Reported-by: Xi Ruoyao <[email protected]> Link: util-linux/util-linux#2867 Signed-off-by: Jiaxun Yang <[email protected]> Signed-off-by: Thomas Bogendoerfer <[email protected]>
1 parent 4cece76 commit 4370b67

File tree

7 files changed

+42
-38
lines changed

7 files changed

+42
-38
lines changed

arch/mips/include/asm/ptrace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ extern unsigned long exception_ip(struct pt_regs *regs);
159159
#define exception_ip(regs) exception_ip(regs)
160160
#define profile_pc(regs) instruction_pointer(regs)
161161

162-
extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall);
162+
extern asmlinkage long syscall_trace_enter(struct pt_regs *regs);
163163
extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
164164

165165
extern void die(const char *, struct pt_regs *) __noreturn;

arch/mips/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ void output_thread_info_defines(void)
101101
OFFSET(TI_CPU, thread_info, cpu);
102102
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
103103
OFFSET(TI_REGS, thread_info, regs);
104+
OFFSET(TI_SYSCALL, thread_info, syscall);
104105
DEFINE(_THREAD_SIZE, THREAD_SIZE);
105106
DEFINE(_THREAD_MASK, THREAD_MASK);
106107
DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);

arch/mips/kernel/ptrace.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,16 +1317,13 @@ long arch_ptrace(struct task_struct *child, long request,
13171317
* Notification of system call entry/exit
13181318
* - triggered by current->work.syscall_trace
13191319
*/
1320-
asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
1320+
asmlinkage long syscall_trace_enter(struct pt_regs *regs)
13211321
{
13221322
user_exit();
13231323

1324-
current_thread_info()->syscall = syscall;
1325-
13261324
if (test_thread_flag(TIF_SYSCALL_TRACE)) {
13271325
if (ptrace_report_syscall_entry(regs))
13281326
return -1;
1329-
syscall = current_thread_info()->syscall;
13301327
}
13311328

13321329
#ifdef CONFIG_SECCOMP
@@ -1335,7 +1332,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
13351332
struct seccomp_data sd;
13361333
unsigned long args[6];
13371334

1338-
sd.nr = syscall;
1335+
sd.nr = current_thread_info()->syscall;
13391336
sd.arch = syscall_get_arch(current);
13401337
syscall_get_arguments(current, regs, args);
13411338
for (i = 0; i < 6; i++)
@@ -1345,23 +1342,23 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
13451342
ret = __secure_computing(&sd);
13461343
if (ret == -1)
13471344
return ret;
1348-
syscall = current_thread_info()->syscall;
13491345
}
13501346
#endif
13511347

13521348
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
13531349
trace_sys_enter(regs, regs->regs[2]);
13541350

1355-
audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
1351+
audit_syscall_entry(current_thread_info()->syscall,
1352+
regs->regs[4], regs->regs[5],
13561353
regs->regs[6], regs->regs[7]);
13571354

13581355
/*
13591356
* Negative syscall numbers are mistaken for rejected syscalls, but
13601357
* won't have had the return value set appropriately, so we do so now.
13611358
*/
1362-
if (syscall < 0)
1359+
if (current_thread_info()->syscall < 0)
13631360
syscall_set_return_value(current, regs, -ENOSYS, 0);
1364-
return syscall;
1361+
return current_thread_info()->syscall;
13651362
}
13661363

13671364
/*

arch/mips/kernel/scall32-o32.S

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ loads_done:
7777
PTR_WD load_a7, bad_stack_a7
7878
.previous
7979

80+
/*
81+
* syscall number is in v0 unless we called syscall(__NR_###)
82+
* where the real syscall number is in a0
83+
*/
84+
subu t2, v0, __NR_O32_Linux
85+
bnez t2, 1f /* __NR_syscall at offset 0 */
86+
LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number
87+
b 2f
88+
1:
89+
LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number
90+
2:
91+
8092
lw t0, TI_FLAGS($28) # syscall tracing enabled?
8193
li t1, _TIF_WORK_SYSCALL_ENTRY
8294
and t0, t1
@@ -114,16 +126,7 @@ syscall_trace_entry:
114126
SAVE_STATIC
115127
move a0, sp
116128

117-
/*
118-
* syscall number is in v0 unless we called syscall(__NR_###)
119-
* where the real syscall number is in a0
120-
*/
121-
move a1, v0
122-
subu t2, v0, __NR_O32_Linux
123-
bnez t2, 1f /* __NR_syscall at offset 0 */
124-
lw a1, PT_R4(sp)
125-
126-
1: jal syscall_trace_enter
129+
jal syscall_trace_enter
127130

128131
bltz v0, 1f # seccomp failed? Skip syscall
129132

arch/mips/kernel/scall64-n32.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ NESTED(handle_sysn32, PT_SIZE, sp)
4444

4545
sd a3, PT_R26(sp) # save a3 for syscall restarting
4646

47+
LONG_S v0, TI_SYSCALL($28) # Store syscall number
48+
4749
li t1, _TIF_WORK_SYSCALL_ENTRY
4850
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
4951
and t0, t1, t0
@@ -72,7 +74,6 @@ syscall_common:
7274
n32_syscall_trace_entry:
7375
SAVE_STATIC
7476
move a0, sp
75-
move a1, v0
7677
jal syscall_trace_enter
7778

7879
bltz v0, 1f # seccomp failed? Skip syscall

arch/mips/kernel/scall64-n64.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ NESTED(handle_sys64, PT_SIZE, sp)
4646

4747
sd a3, PT_R26(sp) # save a3 for syscall restarting
4848

49+
LONG_S v0, TI_SYSCALL($28) # Store syscall number
50+
4951
li t1, _TIF_WORK_SYSCALL_ENTRY
5052
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
5153
and t0, t1, t0
@@ -82,7 +84,6 @@ n64_syscall_exit:
8284
syscall_trace_entry:
8385
SAVE_STATIC
8486
move a0, sp
85-
move a1, v0
8687
jal syscall_trace_enter
8788

8889
bltz v0, 1f # seccomp failed? Skip syscall

arch/mips/kernel/scall64-o32.S

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ loads_done:
7979
PTR_WD load_a7, bad_stack_a7
8080
.previous
8181

82+
/*
83+
* absolute syscall number is in v0 unless we called syscall(__NR_###)
84+
* where the real syscall number is in a0
85+
* note: NR_syscall is the first O32 syscall but the macro is
86+
* only defined when compiling with -mabi=32 (CONFIG_32BIT)
87+
* therefore __NR_O32_Linux is used (4000)
88+
*/
89+
90+
subu t2, v0, __NR_O32_Linux
91+
bnez t2, 1f /* __NR_syscall at offset 0 */
92+
LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number
93+
b 2f
94+
1:
95+
LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number
96+
2:
97+
8298
li t1, _TIF_WORK_SYSCALL_ENTRY
8399
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
84100
and t0, t1, t0
@@ -113,22 +129,7 @@ trace_a_syscall:
113129
sd a7, PT_R11(sp) # For indirect syscalls
114130

115131
move a0, sp
116-
/*
117-
* absolute syscall number is in v0 unless we called syscall(__NR_###)
118-
* where the real syscall number is in a0
119-
* note: NR_syscall is the first O32 syscall but the macro is
120-
* only defined when compiling with -mabi=32 (CONFIG_32BIT)
121-
* therefore __NR_O32_Linux is used (4000)
122-
*/
123-
.set push
124-
.set reorder
125-
subu t1, v0, __NR_O32_Linux
126-
move a1, v0
127-
bnez t1, 1f /* __NR_syscall at offset 0 */
128-
ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
129-
.set pop
130-
131-
1: jal syscall_trace_enter
132+
jal syscall_trace_enter
132133

133134
bltz v0, 1f # seccomp failed? Skip syscall
134135

0 commit comments

Comments
 (0)