percpu_counter.count is an s64, but the function reads it with
sizeof(long long) into a local "long". On 32-bit systems a long is only
4 bytes, so readmem() writes four bytes past the variable and corrupts
the stack frame; with the stack protector enabled this makes "ps" abort:
*** stack smashing detected ***: terminated
Read the value into an int64_t, which matches the kernel's s64, and size
the read from the destination rather than a separate type, so the two
cannot get out of sync again.
Fixes:
https://github.com/crash-utility/crash/issues/212
Signed-off-by: Dave Young <yangrr.2009(a)tsinghua.org.cn>
---
tools.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools.c b/tools.c
index 7dc11aedf56b..cf9d7c0d93c4 100644
--- a/tools.c
+++ b/tools.c
@@ -6960,13 +6960,13 @@ percpu_counter_sum_positive(ulong fbc)
{
int i, count;
ulong addr;
- long ret;
+ int64_t ret;
if (INVALID_MEMBER(percpu_counter_count))
return 0;
readmem(fbc + OFFSET(percpu_counter_count), KVADDR, &ret,
- sizeof(long long), "percpu_counter.count", FAULT_ON_ERROR);
+ sizeof(ret), "percpu_counter.count", FAULT_ON_ERROR);
if (INVALID_MEMBER(percpu_counter_counters)) /* !CONFIG_SMP */
return (ret < 0) ? 0 : ret;
--
2.51.1