@@ -34,7 +34,21 @@ int show_unhandled_signals = 1;
34
34
35
35
static DEFINE_SPINLOCK (die_lock );
36
36
37
- static void dump_kernel_instr (const char * loglvl , struct pt_regs * regs )
37
+ static int copy_code (struct pt_regs * regs , u16 * val , const u16 * insns )
38
+ {
39
+ const void __user * uaddr = (__force const void __user * )insns ;
40
+
41
+ if (!user_mode (regs ))
42
+ return get_kernel_nofault (* val , insns );
43
+
44
+ /* The user space code from other tasks cannot be accessed. */
45
+ if (regs != task_pt_regs (current ))
46
+ return - EPERM ;
47
+
48
+ return copy_from_user_nofault (val , uaddr , sizeof (* val ));
49
+ }
50
+
51
+ static void dump_instr (const char * loglvl , struct pt_regs * regs )
38
52
{
39
53
char str [sizeof ("0000 " ) * 12 + 2 + 1 ], * p = str ;
40
54
const u16 * insns = (u16 * )instruction_pointer (regs );
@@ -43,7 +57,7 @@ static void dump_kernel_instr(const char *loglvl, struct pt_regs *regs)
43
57
int i ;
44
58
45
59
for (i = -10 ; i < 2 ; i ++ ) {
46
- bad = get_kernel_nofault ( val , & insns [i ]);
60
+ bad = copy_code ( regs , & val , & insns [i ]);
47
61
if (!bad ) {
48
62
p += sprintf (p , i == 0 ? "(%04hx) " : "%04hx " , val );
49
63
} else {
@@ -72,7 +86,7 @@ void die(struct pt_regs *regs, const char *str)
72
86
print_modules ();
73
87
if (regs ) {
74
88
show_regs (regs );
75
- dump_kernel_instr (KERN_EMERG , regs );
89
+ dump_instr (KERN_EMERG , regs );
76
90
}
77
91
78
92
cause = regs ? regs -> cause : -1 ;
@@ -105,6 +119,7 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
105
119
print_vma_addr (KERN_CONT " in " , instruction_pointer (regs ));
106
120
pr_cont ("\n" );
107
121
__show_regs (regs );
122
+ dump_instr (KERN_EMERG , regs );
108
123
}
109
124
110
125
force_sig_fault (signo , code , (void __user * )addr );
0 commit comments