• Jiri Slaby's avatar
    vt: keyboard, extend func_buf_lock to readers · 82e61c39
    Jiri Slaby authored
    Both read-side users of func_table/func_buf need locking. Without that,
    one can easily confuse the code by repeatedly setting altering strings
    like:
    while (1)
    	for (a = 0; a < 2; a++) {
    		struct kbsentry kbs = {};
    		strcpy((char *)kbs.kb_string, a ? ".\n" : "88888\n");
    		ioctl(fd, KDSKBSENT, &kbs);
    	}
    
    When that program runs, one can get unexpected output by holding F1
    (note the unxpected period on the last line):
    .
    88888
    .8888
    
    So protect all accesses to 'func_table' (and func_buf) by preexisting
    'func_buf_lock'.
    
    It is easy in 'k_fn' handler as 'puts_queue' is expected not to sleep.
    On the other hand, KDGKBSENT needs a local (atomic) copy of the string
    because copy_to_user can sleep. Use already allocated, but unused
    'kbs->kb_string' for that purpose.
    
    Note that the program above needs at least CAP_SYS_TTY_CONFIG.
    
    This depends on the previous patch and on the func_buf_lock lock added
    in commit 46ca3f73
    
     (tty/vt: fix write/write race in ioctl(KDSKBSENT)
    handler) in 5.2.
    
    Likely fixes CVE-2020-25656.
    
    Cc: <stable@vger.kernel.org>
    Reported-by: default avatarMinh Yuan <yuanmingbuaa@gmail.com>
    Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
    Link: https://lore.kernel.org/r/20201019085517.10176-2-jslaby@suse.cz
    
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    82e61c39
keyboard.c 53.5 KB