Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7a7912a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 3fefc318 b9dd05c7
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -154,30 +154,26 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
	set_fs(fs);
}

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

	/*
	 * We need to switch to kernel mode so that we can use __get_user
	 * to safely read from kernel space.  Note that we now dump the
	 * code first, just in case the backtrace kills us.
	 * Note that we now dump the code first, just in case the backtrace
	 * kills us.
	 */
	fs = get_fs();
	set_fs(KERNEL_DS);

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

		if (thumb)
			bad = __get_user(val, &((u16 *)addr)[i]);
			bad = get_user(val, &((u16 *)addr)[i]);
		else
			bad = __get_user(val, &((u32 *)addr)[i]);
			bad = get_user(val, &((u32 *)addr)[i]);

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

static void dump_instr(const char *lvl, struct pt_regs *regs)
{
	mm_segment_t fs;

	if (!user_mode(regs)) {
		fs = get_fs();
		set_fs(KERNEL_DS);
		__dump_instr(lvl, regs);
		set_fs(fs);
	} else {
		__dump_instr(lvl, regs);
	}
}

#ifdef CONFIG_ARM_UNWIND