diff options
Diffstat (limited to 'drivers/char/nvram.c')
-rw-r--r-- | drivers/char/nvram.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 7cf4518c030f..5eb83c3ca20d 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -110,6 +110,7 @@ #include <linux/spinlock.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/smp_lock.h> #include <asm/system.h> @@ -263,10 +264,16 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, unsigned char contents[NVRAM_BYTES]; unsigned i = *ppos; unsigned char *tmp; - int len; - len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count; - if (copy_from_user(contents, buf, len)) + if (i >= NVRAM_BYTES) + return 0; /* Past EOF */ + + if (count > NVRAM_BYTES - i) + count = NVRAM_BYTES - i; + if (count > NVRAM_BYTES) + return -EFAULT; /* Can't happen, but prove it to gcc */ + + if (copy_from_user(contents, buf, count)) return -EFAULT; spin_lock_irq(&rtc_lock); @@ -274,7 +281,7 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, if (!__nvram_check_checksum()) goto checksum_err; - for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp) + for (tmp = contents; count--; ++i, ++tmp) __nvram_write_byte(*tmp, i); __nvram_set_checksum(); |