Skip to content

Commit e7a7912

Browse files
committed
Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM fix from Russell King: "Last ARM fix for 4.14. This plugs a hole in dump_instr(), which, with certain conditions satisfied, can dump instructions from kernel space" * 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm: ARM: 8720/1: ensure dump_instr() checks addr_limit
2 parents 3fefc31 + b9dd05c commit e7a7912

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

arch/arm/kernel/traps.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,30 +154,26 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
154154
set_fs(fs);
155155
}
156156

157-
static void dump_instr(const char *lvl, struct pt_regs *regs)
157+
static void __dump_instr(const char *lvl, struct pt_regs *regs)
158158
{
159159
unsigned long addr = instruction_pointer(regs);
160160
const int thumb = thumb_mode(regs);
161161
const int width = thumb ? 4 : 8;
162-
mm_segment_t fs;
163162
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
164163
int i;
165164

166165
/*
167-
* We need to switch to kernel mode so that we can use __get_user
168-
* to safely read from kernel space. Note that we now dump the
169-
* code first, just in case the backtrace kills us.
166+
* Note that we now dump the code first, just in case the backtrace
167+
* kills us.
170168
*/
171-
fs = get_fs();
172-
set_fs(KERNEL_DS);
173169

174170
for (i = -4; i < 1 + !!thumb; i++) {
175171
unsigned int val, bad;
176172

177173
if (thumb)
178-
bad = __get_user(val, &((u16 *)addr)[i]);
174+
bad = get_user(val, &((u16 *)addr)[i]);
179175
else
180-
bad = __get_user(val, &((u32 *)addr)[i]);
176+
bad = get_user(val, &((u32 *)addr)[i]);
181177

182178
if (!bad)
183179
p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
@@ -188,8 +184,20 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
188184
}
189185
}
190186
printk("%sCode: %s\n", lvl, str);
187+
}
191188

192-
set_fs(fs);
189+
static void dump_instr(const char *lvl, struct pt_regs *regs)
190+
{
191+
mm_segment_t fs;
192+
193+
if (!user_mode(regs)) {
194+
fs = get_fs();
195+
set_fs(KERNEL_DS);
196+
__dump_instr(lvl, regs);
197+
set_fs(fs);
198+
} else {
199+
__dump_instr(lvl, regs);
200+
}
193201
}
194202

195203
#ifdef CONFIG_ARM_UNWIND

0 commit comments

Comments
 (0)