lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20160627212756.GB22620@dtor-ws>
Date:	Mon, 27 Jun 2016 14:27:56 -0700
From:	Dmitry Torokhov <dmitry.torokhov@...il.com>
To:	Sasha Levin <sasha.levin@...cle.com>
Cc:	gregkh@...uxfoundation.org, jslaby@...e.com, pavel@....cz,
	LKML <linux-kernel@...r.kernel.org>
Subject: Re: tty/vt/keyboard: out of bounds access in do_compute_shiftstate

On Sun, May 29, 2016 at 01:52:44PM -0400, Sasha Levin wrote:
> Hi all,
> 
> I've hit the following while fuzzing with syzkaller inside a KVM tools guest
> running the latest -next kernel:
> 
> [ 2662.777566] BUG: KASAN: global-out-of-bounds in do_compute_shiftstate+0x161/0x370 at addr ffffffffb2e686a0
> 
> [ 2662.777592] Read of size 2 by task syz-executor/30576
> 
> [ 2662.777676] Address belongs to variable plain_map+0x200/0x3540
> 
> [ 2662.777727] CPU: 2 PID: 30576 Comm: syz-executor Tainted: G    B           4.6.0-next-20160527-sasha-00024-g6ab0dc9-dirty #3098
> 
> [ 2662.777792]  1ffff1001635bde7 00000000dc4d92d7 ffff8800b1adefc0 ffffffffa3fd0b37
> 
> [ 2662.777826]  ffffffff00000002 fffffbfff5deeda4 0000000041b58ab3 ffffffffae8dd830
> 
> [ 2662.777862]  ffffffffa3fd09c8 ffffffffa23fa2e8 ffff8800b1adef98 ffff8801d42a20f8
> 
> [ 2662.777868] Call Trace:
> 
> [ 2662.777935] dump_stack (lib/dump_stack.c:53)
> [ 2662.778136] kasan_report_error (include/linux/kasan.h:28 mm/kasan/report.c:211 mm/kasan/report.c:277)
> [ 2662.778265] __asan_report_load2_noabort (mm/kasan/report.c:317)
> [ 2662.778318] do_compute_shiftstate (drivers/tty/vt/keyboard.c:386)
> [ 2662.778332] fn_null (drivers/tty/vt/keyboard.c:625)
> [ 2662.778345] k_spec (drivers/tty/vt/keyboard.c:645)
> [ 2662.778361] kbd_event (drivers/tty/vt/keyboard.c:1459 drivers/tty/vt/keyboard.c:1475)
> [ 2662.778907] input_to_handler (drivers/input/input.c:120 (discriminator 3))
> [ 2662.778926] input_pass_values (drivers/input/input.c:148)
> [ 2662.778944] input_handle_event (drivers/input/input.c:406)
> [ 2662.779015] input_inject_event (include/linux/rcupdate.h:910 drivers/input/input.c:467)
> [ 2662.779034] evdev_do_ioctl (drivers/input/evdev.c:1102)
> [ 2662.779271] evdev_ioctl_handler (drivers/input/evdev.c:1302)
> [ 2662.779305] evdev_ioctl (drivers/input/evdev.c:1312)
> [ 2662.779320] do_vfs_ioctl (fs/ioctl.c:44 fs/ioctl.c:674)
> [ 2662.779463] SyS_ioctl (fs/ioctl.c:689 fs/ioctl.c:680)
> [ 2662.779511] do_syscall_64 (arch/x86/entry/common.c:350)
> [ 2662.779530] entry_SYSCALL64_slow_path (arch/x86/entry/entry_64.S:251)
> [ 2662.779535] Memory state around the buggy address:
> 
> [ 2662.779566]  ffffffffb2e68580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 
> [ 2662.779579]  ffffffffb2e68600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 
> [ 2662.779589] >ffffffffb2e68680: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
> 
> [ 2662.779594]                                ^
> 
> [ 2662.779604]  ffffffffb2e68700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 
> [ 2662.779615]  ffffffffb2e68780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

I think this happens because keymap size in keyboard.c is smaller than
keymaps in input devices. Does the patch below fixes this?

Thanks.

-- 
Dmitry


tty/vt/keyboard: fix OOB access in do_compute_shiftstate()

From: Dmitry Torokhov <dmitry.torokhov@...il.com>

The size of individual keymap in drivers/tty/vt/keyboard.c is NR_KEYS,
which is currently 256, whereas number of keys/buttons in input device (and
therefor in key_down) is much larger - KEY_CNT - 768, and that can cause
out-of-bound access when we do

	sym = U(key_maps[0][k]);

with large 'k'.

To fix it we should not attempt iterating beyond smaller of NR_KEYS and
KEY_CNT.

Also while at it let's switch to for_each_set_bit() instead of open-coding
it.

Reported-by: Sasha Levin <sasha.levin@...cle.com>
Cc: stable@...r.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@...il.com>
---
 drivers/tty/vt/keyboard.c |   30 +++++++++---------------------
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index f973bfc..1e93a37 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -366,34 +366,22 @@ static void to_utf8(struct vc_data *vc, uint c)
 
 static void do_compute_shiftstate(void)
 {
-	unsigned int i, j, k, sym, val;
+	unsigned int k, sym, val;
 
 	shift_state = 0;
 	memset(shift_down, 0, sizeof(shift_down));
 
-	for (i = 0; i < ARRAY_SIZE(key_down); i++) {
-
-		if (!key_down[i])
+	for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
+		sym = U(key_maps[0][k]);
+		if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
 			continue;
 
-		k = i * BITS_PER_LONG;
-
-		for (j = 0; j < BITS_PER_LONG; j++, k++) {
-
-			if (!test_bit(k, key_down))
-				continue;
+		val = KVAL(sym);
+		if (val == KVAL(K_CAPSSHIFT))
+			val = KVAL(K_SHIFT);
 
-			sym = U(key_maps[0][k]);
-			if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
-				continue;
-
-			val = KVAL(sym);
-			if (val == KVAL(K_CAPSSHIFT))
-				val = KVAL(K_SHIFT);
-
-			shift_down[val]++;
-			shift_state |= (1 << val);
-		}
+		shift_down[val]++;
+		shift_state |= BIT(val);
 	}
 }
 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ