android_kernel_oneplus_msm8998/drivers/tty
Sergei Trofimovich e5100e7fa7 tty/vt: fix write/write race in ioctl(KDSKBSENT) handler
commit 46ca3f735f345c9d87383dd3a09fa5d43870770e upstream.

The bug manifests as an attempt to access deallocated memory:

    BUG: unable to handle kernel paging request at ffff9c8735448000
    #PF error: [PROT] [WRITE]
    PGD 288a05067 P4D 288a05067 PUD 288a07067 PMD 7f60c2063 PTE 80000007f5448161
    Oops: 0003 [#1] PREEMPT SMP
    CPU: 6 PID: 388 Comm: loadkeys Tainted: G         C        5.0.0-rc6-00153-g5ded5871030e #91
    Hardware name: Gigabyte Technology Co., Ltd. To be filled by O.E.M./H77M-D3H, BIOS F12 11/14/2013
    RIP: 0010:__memmove+0x81/0x1a0
    Code: 4c 89 4f 10 4c 89 47 18 48 8d 7f 20 73 d4 48 83 c2 20 e9 a2 00 00 00 66 90 48 89 d1 4c 8b 5c 16 f8 4c 8d 54 17 f8 48 c1 e9 03 <f3> 48 a5 4d 89 1a e9 0c 01 00 00 0f 1f 40 00 48 89 d1 4c 8b 1e 49
    RSP: 0018:ffffa1b9002d7d08 EFLAGS: 00010203
    RAX: ffff9c873541af43 RBX: ffff9c873541af43 RCX: 00000c6f105cd6bf
    RDX: 0000637882e986b6 RSI: ffff9c8735447ffb RDI: ffff9c8735447ffb
    RBP: ffff9c8739cd3800 R08: ffff9c873b802f00 R09: 00000000fffff73b
    R10: ffffffffb82b35f1 R11: 00505b1b004d5b1b R12: 0000000000000000
    R13: ffff9c873541af3d R14: 000000000000000b R15: 000000000000000c
    FS:  00007f450c390580(0000) GS:ffff9c873f180000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: ffff9c8735448000 CR3: 00000007e213c002 CR4: 00000000000606e0
    Call Trace:
     vt_do_kdgkb_ioctl+0x34d/0x440
     vt_ioctl+0xba3/0x1190
     ? __bpf_prog_run32+0x39/0x60
     ? mem_cgroup_commit_charge+0x7b/0x4e0
     tty_ioctl+0x23f/0x920
     ? preempt_count_sub+0x98/0xe0
     ? __seccomp_filter+0x67/0x600
     do_vfs_ioctl+0xa2/0x6a0
     ? syscall_trace_enter+0x192/0x2d0
     ksys_ioctl+0x3a/0x70
     __x64_sys_ioctl+0x16/0x20
     do_syscall_64+0x54/0xe0
     entry_SYSCALL_64_after_hwframe+0x49/0xbe

The bug manifests on systemd systems with multiple vtcon devices:
  # cat /sys/devices/virtual/vtconsole/vtcon0/name
  (S) dummy device
  # cat /sys/devices/virtual/vtconsole/vtcon1/name
  (M) frame buffer device

There systemd runs 'loadkeys' tool in tapallel for each vtcon
instance. This causes two parallel ioctl(KDSKBSENT) calls to
race into adding the same entry into 'func_table' array at:

    drivers/tty/vt/keyboard.c:vt_do_kdgkb_ioctl()

The function has no locking around writes to 'func_table'.

The simplest reproducer is to have initrams with the following
init on a 8-CPU machine x86_64:

    #!/bin/sh

    loadkeys -q windowkeys ru4 &
    loadkeys -q windowkeys ru4 &
    loadkeys -q windowkeys ru4 &
    loadkeys -q windowkeys ru4 &

    loadkeys -q windowkeys ru4 &
    loadkeys -q windowkeys ru4 &
    loadkeys -q windowkeys ru4 &
    loadkeys -q windowkeys ru4 &
    wait

The change adds lock on write path only. Reads are still racy.

CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Jiri Slaby <jslaby@suse.com>
Link: https://lkml.org/lkml/2019/2/17/256
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-11 12:23:37 +02:00
..
hvc hvc_opal: don't set tb_ticks_per_usec in udbg_init_opal_common() 2018-08-06 16:24:31 +02:00
ipwireless
serial sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init() 2019-05-16 19:44:57 +02:00
vt tty/vt: fix write/write race in ioctl(KDSKBSENT) handler 2019-06-11 12:23:37 +02:00
amiserial.c
bfin_jtag_comm.c
cyclades.c
ehv_bytechan.c
goldfish.c Revert "tty: goldfish: Fix a parameter of a call to free_irq" 2017-10-21 17:09:06 +02:00
isicom.c
Kconfig tty: ldisc: add sysctl to prevent autoloading of ldiscs 2019-04-27 09:33:54 +02:00
Makefile
metag_da.c
mips_ejtag_fdc.c
moxa.c
moxa.h
mxser.c
mxser.h
n_gsm.c tty: n_gsm: Fix DLCI handling for ADM mode if debug & 2 is not set 2018-05-02 07:53:40 -07:00
n_hdlc.c tty/n_hdlc: fix __might_sleep warning 2019-02-06 19:43:04 +01:00
n_r3964.c
n_tracerouter.c
n_tracesink.c
n_tracesink.h
n_tty.c tty: wipe buffer if not echoing data 2018-12-01 09:46:41 +01:00
nozomi.c tty: nozomi: avoid a harmless gcc warning 2017-04-30 05:49:27 +02:00
pty.c tty: Fix data race in tty_insert_flip_string_fixed_flag 2018-08-06 16:24:36 +02:00
rocket.c tty: rocket: Fix possible buffer overwrite on register_PCI 2018-09-19 22:48:57 +02:00
rocket.h
rocket_int.h
synclink.c
synclink_gt.c
synclinkmp.c
sysrq.c sysrq: Fix warning in sysrq generated crash. 2018-01-17 09:35:28 +01:00
tty_audit.c tty: audit: Fix audit source 2015-11-20 16:19:54 -08:00
tty_buffer.c tty: increase the default flip buffer limit to 2*640K 2019-04-27 09:33:52 +02:00
tty_io.c tty: ldisc: add sysctl to prevent autoloading of ldiscs 2019-04-27 09:33:54 +02:00
tty_ioctl.c termios, tty/tty_baudrate.c: fix buffer overrun 2018-11-21 09:27:42 +01:00
tty_ldisc.c tty: ldisc: add sysctl to prevent autoloading of ldiscs 2019-04-27 09:33:54 +02:00
tty_ldsem.c tty/ldsem: Wake up readers after timed out down_write() 2019-01-26 09:42:45 +01:00
tty_mutex.c tty: Drop krefs for interrupted tty lock 2017-06-14 13:16:26 +02:00
tty_port.c