Skip to content

Commit 219faf2

Browse files
Vasily Gorbikgregkh
authored andcommitted
s390/process: avoid potential reading of freed stack
commit 8769f610fe6d473e5e8e221709c3ac402037da6c upstream. With THREAD_INFO_IN_TASK (which is selected on s390) task's stack usage is refcounted and should always be protected by get/put when touching other task's stack to avoid race conditions with task's destruction code. Fixes: d5c352c ("s390: move thread_info into task_struct") Cc: stable@vger.kernel.org # v4.10+ Acked-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4232789 commit 219faf2

1 file changed

Lines changed: 16 additions & 6 deletions

File tree

arch/s390/kernel/process.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,20 +185,30 @@ unsigned long get_wchan(struct task_struct *p)
185185

186186
if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p))
187187
return 0;
188+
189+
if (!try_get_task_stack(p))
190+
return 0;
191+
188192
low = task_stack_page(p);
189193
high = (struct stack_frame *) task_pt_regs(p);
190194
sf = (struct stack_frame *) p->thread.ksp;
191-
if (sf <= low || sf > high)
192-
return 0;
195+
if (sf <= low || sf > high) {
196+
return_address = 0;
197+
goto out;
198+
}
193199
for (count = 0; count < 16; count++) {
194200
sf = (struct stack_frame *) sf->back_chain;
195-
if (sf <= low || sf > high)
196-
return 0;
201+
if (sf <= low || sf > high) {
202+
return_address = 0;
203+
goto out;
204+
}
197205
return_address = sf->gprs[8];
198206
if (!in_sched_functions(return_address))
199-
return return_address;
207+
goto out;
200208
}
201-
return 0;
209+
out:
210+
put_task_stack(p);
211+
return return_address;
202212
}
203213

204214
unsigned long arch_align_stack(unsigned long sp)

0 commit comments

Comments
 (0)