Friday, January 20, 2012

XKB breaking grabs - CVE-2012-0064

Given that there is a copious amount of misinformation being spread, here is a summary of CVE-2012-0064, straight from a horse's mouth.

Outline of the issue

The bug allows users to work around screen locking (e.g. gnome-screensaver) by hitting Control+Alt+keypad multiply or Control+Alt+keypad divide. This terminates the input grab the screensaver has and thus allows a user to interact with the desktop, skipping the password entry.

Affected versions

Affected is anyone running X server 1.11 or later (or release candidates thereof). So if "Xorg -version" shows something else on your box, stop worrying. I doubt any distribution would have back-ported the patches.

In Fedora/Red Hat land - the only distributions affected are Fedora 16 and current Fedora Rawhide. Both have been fixed, the F16 update is avaialble here. Note that the update is to xkeyboard-config, not to the server itself.

Fedora 15 is not affected. RHEL 4, 5, 6 and thus CentOS 4, 5, 6 and other derivatives are not affected. I believe that most other distributions have now pushed out updates as well, if you want to link to the respective updates, please do so in the comments.

Sergey has also pushed out xkeyboard-config 2.5 today with the fix included.

History of the feature

The X protocol does not allow the server to break grabs. Once a client has a grab, the server must wait for that client to release the grab, terminate, or the grab window to become unviewable. This is an issue when debugging applications - if your client has a keyboard grab, you cannot use the debugger since all key events will go to the client being debugged. To avoid this issue, the X server has had two combinations to break grabs: Control+Alt+Keypad multiply and Control+Alt+Keypad divide. They forced grab termination inside the X server and although against the protocol it made debugging possible. The option required explicit enabling in the xorg.conf.

These options were removed in server 1.4 and disabled since. Which made debugging hard, so last year we merged a patch to bring them back, together with some other features. They are triggered by XKB actions (as they used to be). The plan was to remove the XKB actions from the default keymap so that the action is available on request but not enabled by default. This is where a miscommunication happened, the removal from the default keymap never happened. So server 1.11 and vanilla xkeyboard-config ship with both the actions available and present in the current keymap. As a result, any user can break a grab from any application and thus get around screen locking.

Outline of the fix

To shoot yourself in the foot, you need two items: a gun and a trigger. We have removed the trigger. The fix we've now pushed into xkeyboard-config removes the actions from the default keymap and into an XKB option instead. So the fix does not remove the gun, but it requires the user to screw the trigger in themselves before trying to hurt themselves. In a default configuration, it is thus no longer possible to break the grab of your screensaver.

To re-enable grab debugging, run setxkbmap with "-option grab:break_actions" or enable "Allow breaking grabs with keyboard actions (warning: security risk)" in the "Miscellaneous compatibility options" in your keyboard layout configuration tool of choice.


sqweek said...

Nice post, thanks for the info!

While experimenting with the grab:break_actions option I noticed an oddity - it only seems to take effect if run within the actual graphics environment.

ie. if I run the following in an xterm:

# reset options to default set
$ setxkbmap -option -option ctrl:nocaps -option terminate:ctrl_alt_bksp

$ xkill& sleep 1; setxkbmap -option grab:break_actions

Xkill grabs the cursor, then after one second setkxbmap runs and I can press ctrl-alt-/ to clear xkill's grab.

However if run xkill by itself and switch to a different virtual terminal to run 'setxkbmap -display :1 -option grab:break_actions', when I switch back to my X display ctrl-alt-/ has no effect.

My DISPLAY is definitely :1, and I can see the option has been set via 'setxkbmap -query' - it just doesn't _work_ until I set the option from within the graphical environment itself.

I just thought of another test while writing this - if I ssh into the machine and run setxkbmap -display :1 that way while xkill has a grab, ctrl-alt-/ works as expected. Seems like the x server needs to be visible when setxkbmap runs - does that sound like a bug or is there a rational explanation I'm not aware of?


SamB said...

Wouldn't it be better to bring back an API to control this, though, as requested at ? Apps go haywire like this all too often, and you shouldn't have to choose between debugging apps that take grabs and screensaver locking, anyway.

Though even if that were done, it would be important to wait for screensavers to actually use it before flipping the default for grab:break_actions, since the XF86Misc extensions itself is obviously not going to be reintroduced, so screensavers would need to be adapted to check for and use the new thing.