svn commit: r346549 - stable/11/sys/dev/vt
Ian Lepore
ian at FreeBSD.org
Tue Sep 3 14:07:23 UTC 2019
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);
}
More information about the svn-src-stable-11
mailing list