Summary: In some cases, input events are sent to X servers not currently active, allowing a user to capture passwords. Affected: all versions since X server 1.4 (inclusive) I think Synopsis: If a user vt-switches away from X to a tty, all current input devices are disabled and the server will not receive events for them until the user vt-switches back. In the default configuration, the X server is configured to support input device hotplugging through udev or HAL. If such an event is received while the server is vt-switched away, the server enables the new device. Events from that device will be received and processed by the server. Reproducer (with a tty) 1) start X, open a text editor 2) vt-switch to a tty 3) plug in a USB keyboard 4) use this keyboard to log in on the tty 5) vt-switch back to X 6) user + pwd are visible in the text editor Reproducer (with fast-user switching) 1) select "Switch User" in the GNOME3 top-right menu 2) log in as second user, open text editor 3) vt-switch to first X instance 4) type password to log in as your user 5) vt-switch to second X instance 6) password visible in text editor or: 1) as above 2) vt-switch back to initial user 3) open text editor 4) vt-switch to gdm window, wait for a user to log in 5) vt-switch to second X instance 6) password visible in text editor The above works not only for a new device, simply unplugging and re-plugging the existing keyboard will do. Solution: The server must determine if it is the VT owner when the new device notification is received. If it is not the VT owner, it may add, but must not enable the new device. No upstream patches available at this point. CVE-2013-1940 has been assigned to this issue.
Created attachment 77717 [details] [review] patch to fix flush input This fixes the input flush code to use a larger buffer size so we can drain evdev events.
Correction, the interpretation of the cause was wrong. The server _does_ check whether it is the VT owner and does not enable the device. So this part of the server is correct. The events are sent after VT-switching back because they're still on the fd. When the next event comes on that fd, the driver reads all events off the wire and thus processes the ones from before vt-switching back too. The evdev driver does call xf86FlushInput() to ditch these events, but xf86FlushInput() is the real bug: it reads 4 bytes off the fd until there is none left. The kernel will not write into a buffer smaller than sizeof(struct input_event), the events aren't discarded and show up with the next input from that device.
This is most likely a Linux only problem.
This only happens with the evdev driver. evdev keeps the fd open between PreInit and DEVICE_ON, which is how these events accumulate in the first place. other drivers open and close the fd in PreInit and then re-open it for DEVICE_ON. A quick git log shows this behaviour has been there since at least evdev 2.0.
Comment on attachment 77717 [details] [review] patch to fix flush input Review of attachment 77717 [details] [review]: ----------------------------------------------------------------- Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
CC-ing stable branch maintainer
Embargo date 17 April
This issue is public now. http://bugzilla.redhat.com/CVE-2013-1940 commit 6ca03b9161d33b1d2b55a3a1a913cf88deb2343f Author: Dave Airlie <airlied@gmail.com> Date: Wed Apr 10 16:09:01 2013 +1000 xf86: fix flush input to work with Linux evdev devices.
xorg-server-1.13.4 and xorg-server-1.14.1 have been released with the fixes for this issue. No additional stable releases are planned at this point, users relying on 1.12 or earlier servers will have to apply the patch themselves.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.