agp: fix OOM and buffer overflow
[linux-2.6.git] / drivers / char / nvram.c
index 47e8f7b..166f1e7 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
 
 #include <asm/system.h>
 
+static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt;     /* #times opened */
 static int nvram_open_mode;    /* special open modes */
@@ -296,8 +297,8 @@ checksum_err:
        return -EIO;
 }
 
-static int nvram_ioctl(struct inode *inode, struct file *file,
-                                       unsigned int cmd, unsigned long arg)
+static long nvram_ioctl(struct file *file, unsigned int cmd,
+                       unsigned long arg)
 {
        int i;
 
@@ -308,6 +309,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file,
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
 
+               mutex_lock(&nvram_mutex);
                spin_lock_irq(&rtc_lock);
 
                for (i = 0; i < NVRAM_BYTES; ++i)
@@ -315,6 +317,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file,
                __nvram_set_checksum();
 
                spin_unlock_irq(&rtc_lock);
+               mutex_unlock(&nvram_mutex);
                return 0;
 
        case NVRAM_SETCKS:
@@ -323,9 +326,11 @@ static int nvram_ioctl(struct inode *inode, struct file *file,
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
 
+               mutex_lock(&nvram_mutex);
                spin_lock_irq(&rtc_lock);
                __nvram_set_checksum();
                spin_unlock_irq(&rtc_lock);
+               mutex_unlock(&nvram_mutex);
                return 0;
 
        default:
@@ -422,7 +427,7 @@ static const struct file_operations nvram_fops = {
        .llseek         = nvram_llseek,
        .read           = nvram_read,
        .write          = nvram_write,
-       .ioctl          = nvram_ioctl,
+       .unlocked_ioctl = nvram_ioctl,
        .open           = nvram_open,
        .release        = nvram_release,
 };