Skip to content

Commit 2095574

Browse files
author
Vasily Gorbik
committed
s390/kasan: avoid false positives during stack unwind
Avoid kasan false positive when current task is interrupted in-between stack frame allocation and backchain write instructions leaving new stack frame backchain invalid. In particular if backchain is 0 the unwinder tries to read pt_regs from the stack and might hit kasan poisoned bytes, leading to kasan "stack-out-of-bounds" report. Disable kasan instrumentation of unwinder stack reads, since this limitation couldn't be handled otherwise with current backchain unwinder implementation. Fixes: 78c98f9 ("s390/unwind: introduce stack unwind API") Reported-by: Julian Wiedmann <[email protected]> Tested-by: Benjamin Block <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent ac6639c commit 2095574

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

arch/s390/kernel/unwind_bc.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,36 @@ bool unwind_next_frame(struct unwind_state *state)
4646

4747
regs = state->regs;
4848
if (unlikely(regs)) {
49-
sp = READ_ONCE_TASK_STACK(state->task, regs->gprs[15]);
49+
sp = READ_ONCE_NOCHECK(regs->gprs[15]);
5050
if (unlikely(outside_of_stack(state, sp))) {
5151
if (!update_stack_info(state, sp))
5252
goto out_err;
5353
}
5454
sf = (struct stack_frame *) sp;
55-
ip = READ_ONCE_TASK_STACK(state->task, sf->gprs[8]);
55+
ip = READ_ONCE_NOCHECK(sf->gprs[8]);
5656
reliable = false;
5757
regs = NULL;
5858
} else {
5959
sf = (struct stack_frame *) state->sp;
60-
sp = READ_ONCE_TASK_STACK(state->task, sf->back_chain);
60+
sp = READ_ONCE_NOCHECK(sf->back_chain);
6161
if (likely(sp)) {
6262
/* Non-zero back-chain points to the previous frame */
6363
if (unlikely(outside_of_stack(state, sp))) {
6464
if (!update_stack_info(state, sp))
6565
goto out_err;
6666
}
6767
sf = (struct stack_frame *) sp;
68-
ip = READ_ONCE_TASK_STACK(state->task, sf->gprs[8]);
68+
ip = READ_ONCE_NOCHECK(sf->gprs[8]);
6969
reliable = true;
7070
} else {
7171
/* No back-chain, look for a pt_regs structure */
7272
sp = state->sp + STACK_FRAME_OVERHEAD;
7373
if (!on_stack(info, sp, sizeof(struct pt_regs)))
7474
goto out_stop;
7575
regs = (struct pt_regs *) sp;
76-
if (user_mode(regs))
76+
if (READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE)
7777
goto out_stop;
78-
ip = READ_ONCE_TASK_STACK(state->task, regs->psw.addr);
78+
ip = READ_ONCE_NOCHECK(regs->psw.addr);
7979
reliable = true;
8080
}
8181
}
@@ -132,11 +132,11 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
132132

133133
/* Get the instruction pointer from pt_regs or the stack frame */
134134
if (regs) {
135-
ip = READ_ONCE_TASK_STACK(state->task, regs->psw.addr);
135+
ip = READ_ONCE_NOCHECK(regs->psw.addr);
136136
reliable = true;
137137
} else {
138138
sf = (struct stack_frame *) sp;
139-
ip = READ_ONCE_TASK_STACK(state->task, sf->gprs[8]);
139+
ip = READ_ONCE_NOCHECK(sf->gprs[8]);
140140
reliable = false;
141141
}
142142

0 commit comments

Comments
 (0)