netfilter: ebtables: abort if next_offset is too small
[safe/jmp/linux-2.6] / net / rfkill / core.c
index 6896c0b..c218e07 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/rfkill.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/miscdevice.h>
 #include <linux/wait.h>
@@ -549,6 +550,10 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
        swprev = !!(rfkill->state & RFKILL_BLOCK_SW);
        hwprev = !!(rfkill->state & RFKILL_BLOCK_HW);
        __rfkill_set_sw_state(rfkill, sw);
+       if (hw)
+               rfkill->state |= RFKILL_BLOCK_HW;
+       else
+               rfkill->state &= ~RFKILL_BLOCK_HW;
 
        spin_unlock_irqrestore(&rfkill->lock, flags);
 
@@ -574,6 +579,8 @@ static ssize_t rfkill_name_show(struct device *dev,
 
 static const char *rfkill_get_type_str(enum rfkill_type type)
 {
+       BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_FM + 1);
+
        switch (type) {
        case RFKILL_TYPE_WLAN:
                return "wlan";
@@ -585,11 +592,13 @@ static const char *rfkill_get_type_str(enum rfkill_type type)
                return "wimax";
        case RFKILL_TYPE_WWAN:
                return "wwan";
+       case RFKILL_TYPE_GPS:
+               return "gps";
+       case RFKILL_TYPE_FM:
+               return "fm";
        default:
                BUG();
        }
-
-       BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1);
 }
 
 static ssize_t rfkill_type_show(struct device *dev,
@@ -1087,10 +1096,16 @@ static ssize_t rfkill_fop_write(struct file *file, const char __user *buf,
        struct rfkill_event ev;
 
        /* we don't need the 'hard' variable but accept it */
-       if (count < sizeof(ev) - 1)
+       if (count < RFKILL_EVENT_SIZE_V1 - 1)
                return -EINVAL;
 
-       if (copy_from_user(&ev, buf, sizeof(ev) - 1))
+       /*
+        * Copy as much data as we can accept into our 'ev' buffer,
+        * but tell userspace how much we've copied so it can determine
+        * our API version even in a write() call, if it cares.
+        */
+       count = min(count, sizeof(ev));
+       if (copy_from_user(&ev, buf, count))
                return -EFAULT;
 
        if (ev.op != RFKILL_OP_CHANGE && ev.op != RFKILL_OP_CHANGE_ALL)
@@ -1176,6 +1191,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
 #endif
 
 static const struct file_operations rfkill_fops = {
+       .owner          = THIS_MODULE,
        .open           = rfkill_fop_open,
        .read           = rfkill_fop_read,
        .write          = rfkill_fop_write,