rfkill: introduce RFKILL_STATE_MAX
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Sat, 2 Aug 2008 18:11:00 +0000 (15:11 -0300)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 22 Aug 2008 20:29:57 +0000 (16:29 -0400)
While it is interesting to not add last-enum-markers because it allows gcc
to warn us of switch() statements missing a valid state, we really should
be handling memory corruption on a rfkill state with default clauses,
anyway.

So add RFKILL_STATE_MAX and use it where applicable.  It makes for safer
code in the long run.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/linux/rfkill.h
net/rfkill/rfkill.c

index e92d8e94bb888bbacc17641ad1f78c808aaa1b3c..4cd64b0d9825a6b2bbe33b9a584b1233a03ac54d 100644 (file)
@@ -49,6 +49,7 @@ enum rfkill_state {
        RFKILL_STATE_SOFT_BLOCKED = 0,  /* Radio output blocked */
        RFKILL_STATE_UNBLOCKED    = 1,  /* Radio output allowed */
        RFKILL_STATE_HARD_BLOCKED = 2,  /* Output blocked, non-overrideable */
+       RFKILL_STATE_MAX,               /* marker for last valid state */
 };
 
 /*
index fae7ffade9c93acc02f2441cd7d38e5ca3c00525..47e0b2d232e30c120121e85e10e88902f86f4e52 100644 (file)
@@ -201,6 +201,8 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
                 * BLOCK even a transmitter that is already in state
                 * RFKILL_STATE_HARD_BLOCKED */
                break;
+       default:
+               return -EINVAL;
        }
 
        if (force || state != rfkill->state) {
@@ -234,6 +236,9 @@ static void __rfkill_switch_all(const enum rfkill_type type,
 {
        struct rfkill *rfkill;
 
+       if (unlikely(state >= RFKILL_STATE_MAX))
+               return;
+
        rfkill_global_states[type].current_state = state;
        list_for_each_entry(rfkill, &rfkill_list, node) {
                if ((!rfkill->user_claim) && (rfkill->type == type)) {
@@ -329,9 +334,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
 {
        enum rfkill_state oldstate;
 
-       if (state != RFKILL_STATE_SOFT_BLOCKED &&
-           state != RFKILL_STATE_UNBLOCKED &&
-           state != RFKILL_STATE_HARD_BLOCKED)
+       if (unlikely(state >= RFKILL_STATE_MAX))
                return -EINVAL;
 
        mutex_lock(&rfkill->mutex);
@@ -727,6 +730,8 @@ int __must_check rfkill_register(struct rfkill *rfkill)
                return -EINVAL;
        if (rfkill->type >= RFKILL_TYPE_MAX)
                return -EINVAL;
+       if (rfkill->state >= RFKILL_STATE_MAX)
+               return -EINVAL;
 
        snprintf(dev->bus_id, sizeof(dev->bus_id),
                 "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);