Skip to content

Commit c8e3dd8

Browse files
author
Al Viro
committed
x86 user stack frame reads: switch to explicit __get_user()
rather than relying upon the magic in raw_copy_from_user() Signed-off-by: Al Viro <[email protected]>
1 parent bb6d3fb commit c8e3dd8

File tree

3 files changed

+11
-31
lines changed

3 files changed

+11
-31
lines changed

arch/x86/events/core.c

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,7 +2490,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
24902490
/* 32-bit process in 64-bit kernel. */
24912491
unsigned long ss_base, cs_base;
24922492
struct stack_frame_ia32 frame;
2493-
const void __user *fp;
2493+
const struct stack_frame_ia32 __user *fp;
24942494

24952495
if (!test_thread_flag(TIF_IA32))
24962496
return 0;
@@ -2501,18 +2501,12 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
25012501
fp = compat_ptr(ss_base + regs->bp);
25022502
pagefault_disable();
25032503
while (entry->nr < entry->max_stack) {
2504-
unsigned long bytes;
2505-
frame.next_frame = 0;
2506-
frame.return_address = 0;
2507-
25082504
if (!valid_user_frame(fp, sizeof(frame)))
25092505
break;
25102506

2511-
bytes = __copy_from_user_nmi(&frame.next_frame, fp, 4);
2512-
if (bytes != 0)
2507+
if (__get_user(frame.next_frame, &fp->next_frame))
25132508
break;
2514-
bytes = __copy_from_user_nmi(&frame.return_address, fp+4, 4);
2515-
if (bytes != 0)
2509+
if (__get_user(frame.return_address, &fp->return_address))
25162510
break;
25172511

25182512
perf_callchain_store(entry, cs_base + frame.return_address);
@@ -2533,7 +2527,7 @@ void
25332527
perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
25342528
{
25352529
struct stack_frame frame;
2536-
const unsigned long __user *fp;
2530+
const struct stack_frame __user *fp;
25372531

25382532
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
25392533
/* TODO: We don't support guest os callchain now */
@@ -2546,7 +2540,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
25462540
if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
25472541
return;
25482542

2549-
fp = (unsigned long __user *)regs->bp;
2543+
fp = (void __user *)regs->bp;
25502544

25512545
perf_callchain_store(entry, regs->ip);
25522546

@@ -2558,19 +2552,12 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
25582552

25592553
pagefault_disable();
25602554
while (entry->nr < entry->max_stack) {
2561-
unsigned long bytes;
2562-
2563-
frame.next_frame = NULL;
2564-
frame.return_address = 0;
2565-
25662555
if (!valid_user_frame(fp, sizeof(frame)))
25672556
break;
25682557

2569-
bytes = __copy_from_user_nmi(&frame.next_frame, fp, sizeof(*fp));
2570-
if (bytes != 0)
2558+
if (__get_user(frame.next_frame, &fp->next_frame))
25712559
break;
2572-
bytes = __copy_from_user_nmi(&frame.return_address, fp + 1, sizeof(*fp));
2573-
if (bytes != 0)
2560+
if (__get_user(frame.return_address, &fp->return_address))
25742561
break;
25752562

25762563
perf_callchain_store(entry, frame.return_address);

arch/x86/include/asm/uaccess.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -694,15 +694,6 @@ extern struct movsl_mask {
694694
# include <asm/uaccess_64.h>
695695
#endif
696696

697-
/*
698-
* We rely on the nested NMI work to allow atomic faults from the NMI path; the
699-
* nested NMI paths are careful to preserve CR2.
700-
*
701-
* Caller must use pagefault_enable/disable, or run in interrupt context,
702-
* and also do a uaccess_ok() check
703-
*/
704-
#define __copy_from_user_nmi __copy_from_user_inatomic
705-
706697
/*
707698
* The "unsafe" user accesses aren't really "unsafe", but the naming
708699
* is a big fat warning: you have to not only do the access_ok()

arch/x86/kernel/stacktrace.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ struct stack_frame_user {
9696
};
9797

9898
static int
99-
copy_stack_frame(const void __user *fp, struct stack_frame_user *frame)
99+
copy_stack_frame(const struct stack_frame_user __user *fp,
100+
struct stack_frame_user *frame)
100101
{
101102
int ret;
102103

@@ -105,7 +106,8 @@ copy_stack_frame(const void __user *fp, struct stack_frame_user *frame)
105106

106107
ret = 1;
107108
pagefault_disable();
108-
if (__copy_from_user_inatomic(frame, fp, sizeof(*frame)))
109+
if (__get_user(frame->next_fp, &fp->next_fp) ||
110+
__get_user(frame->ret_addr, &fp->ret_addr))
109111
ret = 0;
110112
pagefault_enable();
111113

0 commit comments

Comments
 (0)