Date: Mon, 22 Apr 2019 13:55:06 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r346549 - stable/11/sys/dev/vt Message-ID: <201904221355.x3MDt6R9024755@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ian Date: Mon Apr 22 13:55:06 2019 New Revision: 346549 URL: https://svnweb.freebsd.org/changeset/base/346549 Log: MFC r342639: When allocating a new keyboard at vt_upgrade() time, unwind any cngrabs done on the old keyboard and then do the corresponding number of grabs on the new keyboard. This fixes a race that can leave the system with a non-functioning keyboard. It goes like this... - The bios claims there is an AT keyboard, atkbd attaches. - SI_SUB_INT_CONFIG_HOOKS runs. - USB probes devices. Devices begin attaching, including disks. - GELI prompts for a password for a just-attached disk, which results in a cngrab() while atkbd is the keyboard. - A USB keyboard attaches. - vt_upgrade() runs and switches the keyboard to the new USB keyboard, but because cngrab was never called for it, it's not activated and keystrokes are ignored. - Now there is no functional keyboard and no way to get one; even plugging in a different USB keyboard doesn't help, because the console is still grabbed, still waiting for a GELI pw. Modified: stable/11/sys/dev/vt/vt_core.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/vt/vt_core.c ============================================================================== --- stable/11/sys/dev/vt/vt_core.c Mon Apr 22 13:51:25 2019 (r346548) +++ stable/11/sys/dev/vt/vt_core.c Mon Apr 22 13:55:06 2019 (r346549) @@ -937,10 +937,22 @@ vt_kbdevent(keyboard_t *kbd, int event, void *arg) static int vt_allocate_keyboard(struct vt_device *vd) { - int idx0, idx; + int grabbed, i, idx0, idx; keyboard_t *k0, *k; keyboard_info_t ki; + /* + * If vt_upgrade() happens while the console is grabbed, we are + * potentially going to switch keyboard devices while the keyboard is in + * use. Unwind the grabbing of the current keyboard first, then we will + * re-grab the new keyboard below, before we return. + */ + if (vd->vd_curwindow == &vt_conswindow) { + grabbed = vd->vd_curwindow->vw_grabbed; + for (i = 0; i < grabbed; ++i) + vtterm_cnungrab(vd->vd_curwindow->vw_terminal); + } + idx0 = kbd_allocate("kbdmux", -1, vd, vt_kbdevent, vd); if (idx0 >= 0) { DPRINTF(20, "%s: kbdmux allocated, idx = %d\n", __func__, idx0); @@ -971,6 +983,11 @@ vt_allocate_keyboard(struct vt_device *vd) } vd->vd_keyboard = idx0; DPRINTF(20, "%s: vd_keyboard = %d\n", __func__, vd->vd_keyboard); + + if (vd->vd_curwindow == &vt_conswindow) { + for (i = 0; i < grabbed; ++i) + vtterm_cngrab(vd->vd_curwindow->vw_terminal); + } return (idx0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904221355.x3MDt6R9024755>