Bug 193192

Summary: vt keymaps with Unicode characters crash X server on start
Product: Ports & Packages Reporter: Stefan Eßer <se>
Component: Individual Port(s)Assignee: freebsd-x11 (Nobody) <x11>
Status: Closed DUPLICATE    
Severity: Affects Many People CC: arved, dumbbell, emaste, thierry
Priority: Normal    
Version: Latest   
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=191459
Attachments:
Description Flags
Work around X11 server crash with vt and Unicode characters >= 0x100 none

Description Stefan Eßer freebsd_committer freebsd_triage 2014-08-31 06:53:15 UTC
The problem is an assumption, that does not hold if the new console driver (vt) is used. 

In x11-drivers/xf86-input-keyboard line 1264ff of bsd_KeyMap.c, an assumption is made, that the character returned will be in the range of 0x00 to 0xff.

#define KD_GET_ENTRY(i,n) \
  eascii_to_x[((keymap.key[i].spcl << (n+1)) & 0x100) + keymap.key[i].map[n]]

[...]

void
KbdGetMapping (InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap)
{
  KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
  KeySym        *k;
  int           i;

#ifndef __bsdi__
  switch (pKbd->consType) {

/*
 * XXX wscons has no GIO_KEYMAP
 */
#if (defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)) && defined(GIO_KEYMAP)
  case SYSCONS:
  case PCVT:
    {
      keymap_t keymap;

      if (ioctl(pInfo->fd, GIO_KEYMAP, &keymap) != -1) {
        for (i = 0; i < keymap.n_keys && i < NUM_KEYCODES; i++)
          if (remap[i]) {
            k = map + (remap[i] << 2);
            k[0] = KD_GET_ENTRY(i,0);           /* non-shifed */
            k[1] = KD_GET_ENTRY(i,1);         /* shifted */
            k[2] = KD_GET_ENTRY(i,4);         /* alt */
            k[3] = KD_GET_ENTRY(i,5);         /* alt - shifted */
            if (k[3] == k[2]) k[3] = NoSymbol;
            if (k[2] == k[1]) k[2] = NoSymbol;
            if (k[1] == k[0]) k[1] = NoSymbol;
            if (k[0] == k[2] && k[1] == k[3])
              k[2] = k[3] = NoSymbol;
          }
      }
    }
    break;
#endif /* SYSCONS || PCVT */

The keymap returned by ioctl(GIO_KEYMAP) used to contain characters 
in the selected locale, which meant it was limited to 8 bit values,
effectively.

Now with Unicode support, larger values (>=0x100) can be found in 
keymap files. In my case, the Euro symbol (0x20ac) was the cause
of an out-of-bounds access to the keymap array in line 1265 of bsd_KbdMap.c (assignment to k[2] for Alt "E").

To reproduce, you need to use the "vt" console driver:

Load any keyboard with Unicode characters beyond 0x100 with kbdcontrol (e.g. kbdcontrol -l de). Then start Xorg and see that it crashes with a segfault when trying to load the keymap.
Comment 1 Stefan Eßer freebsd_committer freebsd_triage 2014-08-31 07:08:24 UTC
Created attachment 146584 [details]
Work around X11 server crash with vt and Unicode characters >= 0x100

The attached patch works around the problem by returning 0 instead of an out-of-range value for Unicode code points >= 0x100. It is meant to be put into the files sub-directory of the x11-drivers/xf86-input-keyboard port.

This is not a fix, but allows to use the X server at least with the keys defined in ISO Latin-1 ...
Comment 2 Thierry Thomas freebsd_committer freebsd_triage 2014-08-31 07:18:05 UTC
See also PR ports/191459
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=191459
Comment 3 Tilman Keskinoz freebsd_committer freebsd_triage 2014-08-31 09:26:47 UTC
over to maintainer
Comment 4 Stefan Eßer freebsd_committer freebsd_triage 2014-09-02 12:43:12 UTC
Just an observation with the patched port (patch attached to this PR applied):

It seems that I can enter all characters, including e.g. the Euro sign (U+20AC), as verified in a terminal window and with xev.

Without the patch, the X server does not start at all (if a keymap with characters >= 0x100 is loaded). 

With the patch, the X server starts and I do not see what's missing ;-)

Since 10.1 will have vt enabled by default and I plan to MFC a version of rc.d/syscons, that selects a vt keymap matching a syscons keymap specified in rc.conf, this may hurt people that upgrade an existing system to 10.1.

They'll have a working keyboard (with localized keymap) on the console, but cannot any longer start the X server.

Therefore, I'd want to argue for adding this work-around to the xorg-input-keyboard port, until a better solution is available.
Comment 5 Jean-Sébastien Pédron freebsd_committer freebsd_triage 2014-09-09 09:28:58 UTC
A modified patch was committed in r367714 in the ports tree; see 191459.

Thank you!

*** This bug has been marked as a duplicate of bug 191459 ***