Add KD_X console mode to avoid keyboard passthrough
Subsystems (2)
PATCH 1/1 Add KD_X console mode to avoid keyboard passthrough
When using the evdev input driver, X currently claims the devices exclusively in order to prevent characters leaking through to the underlying VT. This has the downside that other consumers of input events no longer receive the keys - rfkill and mouseemu no longer work in the kernel, and hal is unable to pass through input events. Removing the exclusive access results in events being passed through to the underlying VT, which may result in leaking sensitive information.
This patch adds an extra KD_X mode. It's semantically identical to KD_GRAPHICS, except that keyboard events are no longer sent to the console device. This allows X to avoid exclusive access without breaking any applications which depend upon the existing KD_GRAPHICS semantics.
---
drivers/char/keyboard.c +4 -0
@@ -1298,6 +1298,10 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)static void kbd_event (struct input_handle *handle,unsigned int event_type,unsigned int event_code,int value) { +struct vc_data *vc = vc_cons[fg_console].d; + +if (vc->vc_mode ==KD_X ) +return ;if (event_type ==EV_MSC && event_code ==MSC_RAW &&HW_RAW (handle->dev))kbd_rawcode (value);if (event_type ==EV_KEY )
drivers/char/vt.c +14 -7
@@ -601,7 +601,8 @@ static void hide_cursor(struct vc_data *vc)static void set_cursor (struct vc_data *vc) {if (!IS_FG (vc) || console_blanked || - vc->vc_mode ==KD_GRAPHICS ) + vc->vc_mode ==KD_GRAPHICS || + vc->vc_mode ==KD_X )return ;if (vc->vc_deccm) {if (vc == sel_cons)
@@ -696,7 +697,8 @@ void redraw_screen(struct vc_data *vc, int is_switch)update_attr (vc);clear_buffer_attributes (vc); } -if (update && vc->vc_mode !=KD_GRAPHICS ) +if (update && vc->vc_mode !=KD_GRAPHICS && + vc->vc_mode !=KD_X )do_update_region (vc, vc->vc_origin, vc->vc_screenbuf_size /2 ); }set_cursor (vc);
@@ -790,7 +792,8 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,/* Resizes the resolution of the display adapater */ int err =0 ; -if (vc->vc_mode !=KD_GRAPHICS && vc->vc_sw->con_resize) +if (vc->vc_mode !=KD_GRAPHICS && vc->vc_mode !=KD_X && + vc->vc_sw->con_resize) err = vc->vc_sw->con_resize (vc, width, height, user);return err;
@@ -2426,7 +2429,8 @@ int set_console(int nr)struct vc_data *vc = vc_cons[fg_console].d;if (!vc_cons_allocated (nr) || vt_dont_switch || - (vc->vt_mode.mode ==VT_AUTO && vc->vc_mode ==KD_GRAPHICS )) { + (vc->vt_mode.mode ==VT_AUTO && (vc->vc_mode ==KD_GRAPHICS || + vc->vc_mode ==KD_X ))) {/* * Console switch will fail in console_callback() or
@@ -3098,7 +3102,8 @@ static int con_is_graphics(const struct consw *csw, int first, int last)for (i = first; i <= last; i++) {struct vc_data *vc = vc_cons[i].d; -if (vc && vc->vc_mode ==KD_GRAPHICS ) { +if (vc && (vc->vc_mode ==KD_GRAPHICS || + vc->vc_mode ==KD_X )) { retval =1 ;break ; }
@@ -3759,7 +3764,9 @@ void poke_blanked_console(void)del_timer (&console_timer); blank_timer_expired =0 ; -if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode ==KD_GRAPHICS ) +if (ignore_poke || !vc_cons[fg_console].d || + vc_cons[fg_console].d->vc_mode ==KD_GRAPHICS || + vc_cons[fg_console].d->vc_mode ==KD_X )return ;if (console_blanked)unblank_screen ();
@@ -3777,7 +3784,7 @@ static void set_palette(struct vc_data *vc) {WARN_CONSOLE_UNLOCKED (); -if (vc->vc_mode !=KD_GRAPHICS ) +if (vc->vc_mode !=KD_GRAPHICS && vc->vc_mode !=KD_X ) vc->vc_sw->con_set_palette (vc, color_table); }
drivers/char/vt_ioctl.c +3 -1
@@ -488,6 +488,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,if (!perm) goto eperm;switch (arg) { +case KD_X : +break ;case KD_GRAPHICS :break ;case KD_TEXT0 :
@@ -1383,7 +1385,7 @@ void change_console(struct vc_data *new_vc)/* * Ignore all switches in KD_GRAPHICS+VT_AUTO mode */ -if (vc->vc_mode ==KD_GRAPHICS ) +if (vc->vc_mode ==KD_GRAPHICS || vc->vc_mode ==KD_X )return ;complete_change_console (new_vc);
include/linux/kd.h +3 -0
@@ -45,6 +45,9 @@ struct consolefontdesc {#define KD_GRAPHICS 0x01#define KD_TEXT0 0x02/* obsolete */ #define KD_TEXT1 0x03/* obsolete */ +#define KD_X 0x04/* Like KD_GRAPHICS, but doesn't allow +input events to pass through to +/dev/console */ #define KDGETMODE 0x4B3B/* get current mode */ #define KDMAPDISP 0x4B3C/* map display into address space */
Signature · 1 line
Matthew Garrett | [email protected]
Hi Matthew,
Quoted 8 lines · Matthew Garrett
When using the evdev input driver, X currently claims the devices exclusively in order to prevent characters leaking through to the underlying VT. This has the downside that other consumers of input events no longer receive the keys - rfkill and mouseemu no longer work in the kernel, and hal is unable to pass through input events. Removing the exclusive access results in events being passed through to the underlying VT, which may result in leaking sensitive information.
Quoted 5 lines
This patch adds an extra
KD_Xmode. It's semantically identical toKD_GRAPHICS, except that keyboard events are no longer sent to the console device. This allows X to avoid exclusive access without breaking any applications which depend upon the existingKD_GRAPHICSsemantics.
Is this really needed? The current X does not leak anything onto its VT and the new one should not have either, unless they forget to switch virtual console into raw mode. Plus, if you make everything work with KD_GRAPHICS you don't have to have new kernel.
drivers/char/keyboard.c static void kbd_keycode(unsigned int keycode, int down, int hw_raw) · line 1304
Quoted 13 lines
drivers/char/keyboard.c +4
-0@@ -1298,6 +1298,10 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)static void kbd_event (struct input_handle *handle,unsigned int event_type,unsigned int event_code,int value) { +struct vc_data *vc = vc_cons[fg_console].d; + +if (vc->vc_mode ==KD_X ) +return ;
This surely kills SysRq handling.
Quoted 3 lines
drivers/char/keyboard.c +0
-0if (event_type ==EV_MSC && event_code ==MSC_RAW &&HW_RAW (handle->dev))kbd_rawcode (value);if (event_type ==EV_KEY )
Signature · 1 line
Dmitry
Yeah, looks like evdev just wasn't switching the console into raw mode - the old kbd driver did. Thanks for that, we'll go with that approach.
Signature · 1 line
Matthew Garrett | [email protected]