Commit e1443d28 authored by Stephen Chandler Paul's avatar Stephen Chandler Paul Committed by Dmitry Torokhov

Input: i8042 - add unmask_kbd_data option

A big problem with the current i8042 debugging option is that it outputs
data going to and from the keyboard by default. As a result, many dmesg
logs uploaded by users will unintentionally contain sensitive information
such as their password, as such it's probably a good idea not to output
data coming from the keyboard unless specifically enabled by the user.
Signed-off-by: default avatarStephen Chandler Paul <cpaul@redhat.com>
Reviewed-by: default avatarAndreas Mohr <andim2@users.sf.net>
Reviewed-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 339d6b88
...@@ -1274,6 +1274,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -1274,6 +1274,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
<bus_id>,<clkrate> <bus_id>,<clkrate>
i8042.debug [HW] Toggle i8042 debug mode i8042.debug [HW] Toggle i8042 debug mode
i8042.unmask_kbd_data
[HW] Enable printing of interrupt data from the KBD port
(disabled by default, and as a pre-condition
requires that i8042.debug=1 be enabled)
i8042.direct [HW] Put keyboard port into non-translated mode i8042.direct [HW] Put keyboard port into non-translated mode
i8042.dumbkbd [HW] Pretend that controller can only read data from i8042.dumbkbd [HW] Pretend that controller can only read data from
keyboard and cannot control its state keyboard and cannot control its state
......
...@@ -88,6 +88,10 @@ MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings"); ...@@ -88,6 +88,10 @@ MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
static bool i8042_debug; static bool i8042_debug;
module_param_named(debug, i8042_debug, bool, 0600); module_param_named(debug, i8042_debug, bool, 0600);
MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off"); MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
static bool i8042_unmask_kbd_data;
module_param_named(unmask_kbd_data, i8042_unmask_kbd_data, bool, 0600);
MODULE_PARM_DESC(unmask_kbd_data, "Unconditional enable (may reveal sensitive data) of normally sanitize-filtered kbd data traffic debug log [pre-condition: i8042.debug=1 enabled]");
#endif #endif
static bool i8042_bypass_aux_irq_test; static bool i8042_bypass_aux_irq_test;
...@@ -116,6 +120,7 @@ struct i8042_port { ...@@ -116,6 +120,7 @@ struct i8042_port {
struct serio *serio; struct serio *serio;
int irq; int irq;
bool exists; bool exists;
bool driver_bound;
signed char mux; signed char mux;
}; };
...@@ -133,6 +138,7 @@ static bool i8042_kbd_irq_registered; ...@@ -133,6 +138,7 @@ static bool i8042_kbd_irq_registered;
static bool i8042_aux_irq_registered; static bool i8042_aux_irq_registered;
static unsigned char i8042_suppress_kbd_ack; static unsigned char i8042_suppress_kbd_ack;
static struct platform_device *i8042_platform_device; static struct platform_device *i8042_platform_device;
static struct notifier_block i8042_kbd_bind_notifier_block;
static irqreturn_t i8042_interrupt(int irq, void *dev_id); static irqreturn_t i8042_interrupt(int irq, void *dev_id);
static bool (*i8042_platform_filter)(unsigned char data, unsigned char str, static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
...@@ -528,8 +534,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) ...@@ -528,8 +534,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
port = &i8042_ports[port_no]; port = &i8042_ports[port_no];
serio = port->exists ? port->serio : NULL; serio = port->exists ? port->serio : NULL;
dbg("%02x <- i8042 (interrupt, %d, %d%s%s)\n", filter_dbg(port->driver_bound, data, "<- i8042 (interrupt, %d, %d%s%s)\n",
data, port_no, irq, port_no, irq,
dfl & SERIO_PARITY ? ", bad parity" : "", dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : ""); dfl & SERIO_TIMEOUT ? ", timeout" : "");
...@@ -1438,6 +1444,29 @@ static int __init i8042_setup_kbd(void) ...@@ -1438,6 +1444,29 @@ static int __init i8042_setup_kbd(void)
return error; return error;
} }
static int i8042_kbd_bind_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
struct serio *serio = to_serio_port(dev);
struct i8042_port *port = serio->port_data;
if (serio != i8042_ports[I8042_KBD_PORT_NO].serio)
return 0;
switch (action) {
case BUS_NOTIFY_BOUND_DRIVER:
port->driver_bound = true;
break;
case BUS_NOTIFY_UNBIND_DRIVER:
port->driver_bound = false;
break;
}
return 0;
}
static int __init i8042_probe(struct platform_device *dev) static int __init i8042_probe(struct platform_device *dev)
{ {
int error; int error;
...@@ -1507,6 +1536,10 @@ static struct platform_driver i8042_driver = { ...@@ -1507,6 +1536,10 @@ static struct platform_driver i8042_driver = {
.shutdown = i8042_shutdown, .shutdown = i8042_shutdown,
}; };
static struct notifier_block i8042_kbd_bind_notifier_block = {
.notifier_call = i8042_kbd_bind_notifier,
};
static int __init i8042_init(void) static int __init i8042_init(void)
{ {
struct platform_device *pdev; struct platform_device *pdev;
...@@ -1528,6 +1561,7 @@ static int __init i8042_init(void) ...@@ -1528,6 +1561,7 @@ static int __init i8042_init(void)
goto err_platform_exit; goto err_platform_exit;
} }
bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
panic_blink = i8042_panic_blink; panic_blink = i8042_panic_blink;
return 0; return 0;
...@@ -1543,6 +1577,7 @@ static void __exit i8042_exit(void) ...@@ -1543,6 +1577,7 @@ static void __exit i8042_exit(void)
platform_driver_unregister(&i8042_driver); platform_driver_unregister(&i8042_driver);
i8042_platform_exit(); i8042_platform_exit();
bus_unregister_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
panic_blink = NULL; panic_blink = NULL;
} }
......
...@@ -73,6 +73,17 @@ static unsigned long i8042_start_time; ...@@ -73,6 +73,17 @@ static unsigned long i8042_start_time;
printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \ printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \
(int) (jiffies - i8042_start_time), ##arg); \ (int) (jiffies - i8042_start_time), ##arg); \
} while (0) } while (0)
#define filter_dbg(filter, data, format, args...) \
do { \
if (!i8042_debug) \
break; \
\
if (!filter || i8042_unmask_kbd_data) \
dbg("%02x " format, data, ##args); \
else \
dbg("** " format, ##args); \
} while (0)
#else #else
#define dbg_init() do { } while (0) #define dbg_init() do { } while (0)
#define dbg(format, arg...) \ #define dbg(format, arg...) \
...@@ -80,6 +91,8 @@ static unsigned long i8042_start_time; ...@@ -80,6 +91,8 @@ static unsigned long i8042_start_time;
if (0) \ if (0) \
printk(KERN_DEBUG pr_fmt(format), ##arg); \ printk(KERN_DEBUG pr_fmt(format), ##arg); \
} while (0) } while (0)
#define filter_dbg(filter, data, format, args...) do { } while (0)
#endif #endif
#endif /* _I8042_H */ #endif /* _I8042_H */
...@@ -49,8 +49,6 @@ static DEFINE_MUTEX(serio_mutex); ...@@ -49,8 +49,6 @@ static DEFINE_MUTEX(serio_mutex);
static LIST_HEAD(serio_list); static LIST_HEAD(serio_list);
static struct bus_type serio_bus;
static void serio_add_port(struct serio *serio); static void serio_add_port(struct serio *serio);
static int serio_reconnect_port(struct serio *serio); static int serio_reconnect_port(struct serio *serio);
static void serio_disconnect_port(struct serio *serio); static void serio_disconnect_port(struct serio *serio);
...@@ -1017,7 +1015,7 @@ irqreturn_t serio_interrupt(struct serio *serio, ...@@ -1017,7 +1015,7 @@ irqreturn_t serio_interrupt(struct serio *serio,
} }
EXPORT_SYMBOL(serio_interrupt); EXPORT_SYMBOL(serio_interrupt);
static struct bus_type serio_bus = { struct bus_type serio_bus = {
.name = "serio", .name = "serio",
.drv_groups = serio_driver_groups, .drv_groups = serio_driver_groups,
.match = serio_bus_match, .match = serio_bus_match,
...@@ -1029,6 +1027,7 @@ static struct bus_type serio_bus = { ...@@ -1029,6 +1027,7 @@ static struct bus_type serio_bus = {
.pm = &serio_pm_ops, .pm = &serio_pm_ops,
#endif #endif
}; };
EXPORT_SYMBOL(serio_bus);
static int __init serio_init(void) static int __init serio_init(void)
{ {
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <uapi/linux/serio.h> #include <uapi/linux/serio.h>
extern struct bus_type serio_bus;
struct serio { struct serio {
void *port_data; void *port_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment