[PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF

From: Henrique de Moraes Holschuh
Date: Sun May 18 2008 - 14:58:12 EST


SW_RFKILL_ALL is the "emergency power-off all radios" input event. It must
be handled, and must always do the same thing as far as the rfkill system
is concerned: all transmitters are to go *immediately* offline.

For safety, do NOT allow userspace to override EV_SW SW_RFKILL_ALL OFF. As
long as rfkill-input is loaded, that event will *always* be processed, and
it will *always* force all rfkill switches to disable all wireless
transmitters, regardless of user_claim attribute or anything else.

Signed-off-by: Henrique de Moraes Holschuh <hmh@xxxxxxxxxx>
Cc: Ivo van Doorn <IvDoorn@xxxxxxxxx>
Cc: Dmitry Torokhov <dtor@xxxxxxx>
---
net/rfkill/rfkill-input.c | 29 ++++++++++++++---------------
net/rfkill/rfkill-input.h | 1 +
net/rfkill/rfkill.c | 18 ++++++++++++++++++
3 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 29c13d3..0fadeed 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -127,21 +127,20 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
switch (code) {
case SW_RFKILL_ALL:
/* EVERY radio type. data != 0 means radios ON */
- rfkill_schedule_set(&rfkill_wwan,
- (data)? RFKILL_STATE_ON:
- RFKILL_STATE_OFF);
- rfkill_schedule_set(&rfkill_wimax,
- (data)? RFKILL_STATE_ON:
- RFKILL_STATE_OFF);
- rfkill_schedule_set(&rfkill_uwb,
- (data)? RFKILL_STATE_ON:
- RFKILL_STATE_OFF);
- rfkill_schedule_set(&rfkill_bt,
- (data)? RFKILL_STATE_ON:
- RFKILL_STATE_OFF);
- rfkill_schedule_set(&rfkill_wlan,
- (data)? RFKILL_STATE_ON:
- RFKILL_STATE_OFF);
+ /* handle EPO (emergency power off) through shortcut */
+ if (data) {
+ rfkill_schedule_set(&rfkill_wwan,
+ RFKILL_STATE_ON);
+ rfkill_schedule_set(&rfkill_wimax,
+ RFKILL_STATE_ON);
+ rfkill_schedule_set(&rfkill_uwb,
+ RFKILL_STATE_ON);
+ rfkill_schedule_set(&rfkill_bt,
+ RFKILL_STATE_ON);
+ rfkill_schedule_set(&rfkill_wlan,
+ RFKILL_STATE_ON);
+ } else
+ rfkill_epo();
break;
default:
break;
diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h
index 4dae500..f63d050 100644
--- a/net/rfkill/rfkill-input.h
+++ b/net/rfkill/rfkill-input.h
@@ -12,5 +12,6 @@
#define __RFKILL_INPUT_H

void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
+void rfkill_epo(void);

#endif /* __RFKILL_INPUT_H */
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index ba25bde..fdde692 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -182,6 +182,24 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
EXPORT_SYMBOL(rfkill_switch_all);

/**
+ * rfkill_epo - emergency power off all transmitters
+ *
+ * This kicks all rfkill devices to RFKILL_STATE_OFF, ignoring
+ * everything in its path but rfkill_mutex.
+ */
+void rfkill_epo(void)
+{
+ struct rfkill *rfkill;
+
+ mutex_lock(&rfkill_mutex);
+ list_for_each_entry(rfkill, &rfkill_list, node) {
+ rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1);
+ }
+ mutex_unlock(&rfkill_mutex);
+}
+EXPORT_SYMBOL_GPL(rfkill_epo);
+
+/**
* rfkill_force_state - Force the internal rfkill radio state
* @rfkill: pointer to the rfkill class to modify.
* @state: the current radio state the class should be forced to.
--
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/