Skip to content

Commit 489e966

Browse files
Jens Remushcahca
authored andcommitted
s390/stacktrace: Do not fallback to RA register
The logic to fallback to the return address (RA) register value in the topmost frame when stack tracing using back chain is broken in multiple ways: When assuming the RA register 14 has not been saved yet one must assume that a new user stack frame has not been allocated either. Therefore the back chain would not contain the stack pointer (SP) at entry, but the caller's SP at its entry instead. Therefore when falling back to the RA register 14 value it would also be necessary to fallback to the SP register 15 value. Otherwise an invalid combination of RA register 14 and caller's SP at its entry (from the back chain) is used. In the topmost frame the back chain contains either the caller's SP at its entry (before having allocated a new stack frame in the prologue), the SP at entry (after having allocated a new stack frame), or an uninitialized value (during static/dynamic stack allocation). In both cases where the back chain is valid either the caller or prologue must have saved its respective RA to the respective frame. Therefore, if the RA obtained from the frame pointed to by the back chain is invalid, this does not indicate that the IP in the topmost frame is still early in the prologue and the RA has not been saved. Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Jens Remus <jremus@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent af241e6 commit 489e966

1 file changed

Lines changed: 2 additions & 16 deletions

File tree

arch/s390/kernel/stacktrace.c

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo
104104
struct stack_frame_vdso_wrapper __user *sf_vdso;
105105
struct stack_frame_user __user *sf;
106106
unsigned long ip, sp;
107-
bool first = true;
108107

109108
if (!current->mm)
110109
return;
@@ -133,24 +132,11 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo
133132
if (__get_user(ip, &sf->gprs[8]))
134133
break;
135134
}
136-
/* Sanity check: ABI requires SP to be 8 byte aligned. */
137-
if (sp & 0x7)
135+
/* Validate SP and RA (ABI requires SP to be 8 byte aligned). */
136+
if (sp & 0x7 || ip_invalid(ip))
138137
break;
139-
if (ip_invalid(ip)) {
140-
/*
141-
* If the instruction address is invalid, and this
142-
* is the first stack frame, assume r14 has not
143-
* been written to the stack yet. Otherwise exit.
144-
*/
145-
if (!first)
146-
break;
147-
ip = regs->gprs[14];
148-
if (ip_invalid(ip))
149-
break;
150-
}
151138
if (!store_ip(consume_entry, cookie, entry, perf, ip))
152139
break;
153-
first = false;
154140
}
155141
pagefault_enable();
156142
}

0 commit comments

Comments
 (0)