sparc64: perf: Add sanity checking on addresses in user stack
Processes are getting killed (sigbus or segv) while walking userspace callchains when using perf. In some instances I have seen ufp = 0x7ff which does not seem like a proper stack address. This patch adds a function to run validity checks against the address before attempting the copy_from_user. The checks are copied from the x86 version as a start point with the addition of a 4-byte alignment check. Signed-off-by: David Ahern <david.ahern@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
2bf7c3efc3
commit
b69fb7699c
@@ -1741,6 +1741,16 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
|
||||
} while (entry->nr < PERF_MAX_STACK_DEPTH);
|
||||
}
|
||||
|
||||
static inline int
|
||||
valid_user_frame(const void __user *fp, unsigned long size)
|
||||
{
|
||||
/* addresses should be at least 4-byte aligned */
|
||||
if (((unsigned long) fp) & 3)
|
||||
return 0;
|
||||
|
||||
return (__range_not_ok(fp, size, TASK_SIZE) == 0);
|
||||
}
|
||||
|
||||
static void perf_callchain_user_64(struct perf_callchain_entry *entry,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
@@ -1753,6 +1763,9 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry,
|
||||
unsigned long pc;
|
||||
|
||||
usf = (struct sparc_stackf __user *)ufp;
|
||||
if (!valid_user_frame(usf, sizeof(sf)))
|
||||
break;
|
||||
|
||||
if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
|
||||
break;
|
||||
|
||||
|
Reference in New Issue
Block a user