Commit a01c7800 authored by H. Peter Anvin's avatar H. Peter Anvin

nvram: Fix write beyond end condition; prove to gcc copy is safe

In nvram_write, first of all, correctly handle the case where the file
pointer is already beyond the end; we should return EOF in that case.

Second, make the logic a bit more explicit so that gcc can statically
prove that the copy_from_user() is safe.  Once the condition of the
beyond-end filepointer is eliminated, the copy is safe but gcc can't
prove it, causing build failures for i386 allyesconfig.

Third, eliminate the entirely superfluous variable "len", and just use
the passed-in variable "count" instead.
Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <tip-*@git.kernel.org>
parent b9255850
...@@ -264,10 +264,16 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, ...@@ -264,10 +264,16 @@ static ssize_t nvram_write(struct file *file, const char __user *buf,
unsigned char contents[NVRAM_BYTES]; unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos; unsigned i = *ppos;
unsigned char *tmp; unsigned char *tmp;
int len;
len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count; if (i >= NVRAM_BYTES)
if (copy_from_user(contents, buf, len)) 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; return -EFAULT;
spin_lock_irq(&rtc_lock); spin_lock_irq(&rtc_lock);
...@@ -275,7 +281,7 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, ...@@ -275,7 +281,7 @@ static ssize_t nvram_write(struct file *file, const char __user *buf,
if (!__nvram_check_checksum()) if (!__nvram_check_checksum())
goto checksum_err; 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_write_byte(*tmp, i);
__nvram_set_checksum(); __nvram_set_checksum();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment