From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758718Ab0HKX5c (ORCPT ); Wed, 11 Aug 2010 19:57:32 -0400 Received: from kroah.org ([198.145.64.141]:40009 "EHLO coco.kroah.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758673Ab0HKX5Z (ORCPT ); Wed, 11 Aug 2010 19:57:25 -0400 X-Mailbox-Line: From gregkh@clark.site Wed Aug 11 16:54:55 2010 Message-Id: <20100811235455.886413665@clark.site> User-Agent: quilt/0.48-11.2 Date: Wed, 11 Aug 2010 16:53:44 -0700 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: stable-review@kernel.org, torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, "H. Peter Anvin" , Arjan van de Ven , Wim Van Sebroeck , Frederic Weisbecker , Stephen Hemminger Subject: [003/111] nvram: Fix write beyond end condition; prove to gcc copy is safe In-Reply-To: <20100811235623.GA24440@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2.6.32-stable review patch. If anyone has any objections, please let us know. ------------------ From: H. Peter Anvin commit a01c7800420d2c294ca403988488a635d4087a6d upstream. 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: H. Peter Anvin Cc: Arjan van de Ven Cc: Andrew Morton Cc: Wim Van Sebroeck Cc: Frederic Weisbecker LKML-Reference: Cc: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- drivers/char/nvram.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -265,10 +265,16 @@ static ssize_t nvram_write(struct file * 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); @@ -276,7 +282,7 @@ static ssize_t nvram_write(struct file * 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();