From patchwork Wed May 25 10:25:57 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "THOMSON, Adam (Adam)" X-Patchwork-Id: 97322 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D1DD5B6F92 for ; Wed, 25 May 2011 20:28:23 +1000 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by bombadil.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QPBIX-0005ME-T4; Wed, 25 May 2011 10:26:42 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QPBIW-0000Uc-9I; Wed, 25 May 2011 10:26:40 +0000 Received: from smail3.alcatel.fr ([62.23.212.56]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QPBIS-0000UJ-9p for linux-mtd@lists.infradead.org; Wed, 25 May 2011 10:26:37 +0000 Received: from FRMRSSXCHHUB01.dc-m.alcatel-lucent.com (FRMRSSXCHHUB01.dc-m.alcatel-lucent.com [135.120.45.61]) by smail3.alcatel.fr (8.14.3/8.14.3/ICT) with ESMTP id p4PAMmtp017951 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NOT) for ; Wed, 25 May 2011 12:26:28 +0200 Received: from FRMRSSXCHMBSC1.dc-m.alcatel-lucent.com ([135.120.45.44]) by FRMRSSXCHHUB01.dc-m.alcatel-lucent.com ([135.120.45.61]) with mapi; Wed, 25 May 2011 12:25:59 +0200 From: "THOMSON, Adam (Adam)" To: "linux-mtd@lists.infradead.org" Date: Wed, 25 May 2011 12:25:57 +0200 Subject: [PATCH v2] nand: nand_base: Always initialise oob_poi before writing OOB data Thread-Topic: [PATCH v2] nand: nand_base: Always initialise oob_poi before writing OOB data Thread-Index: AcwaxiLx2Mrli3kXSc+hJ055wQwoNA== Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.64 on 155.132.188.83 X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110525_062636_661941_7E599C77 X-CRM114-Status: GOOD ( 17.45 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [62.23.212.56 listed in list.dnswl.org] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org In nand_do_write_ops() code it is possible for a caller to provide ops.oobbuf populated and ops.mode == MTD_OOB_AUTO, which currently means that the chip->oob_poi buffer isn't initialised to all 0xFF. The nand_fill_oob() method then carries out the task of copying the provided OOB data to oob_poi, but with MTD_OOB_AUTO it skips areas marked as unavailable by the layout struct, including the bad block marker bytes. An example of this causing issues is when the last OOB data read was from the start of a bad block where the markers are not 0xFF, and the caller wishes to write new OOB data at the beginning of another block. In this scenario the caller would provide OOB data, but nand_fill_oob() would skip the bad block marker bytes in oob_poi before copying the OOB data provided by the caller. This means that when the OOB data is written back to NAND, the block is inadvertently marked as bad without the caller knowing. This has been witnessed when using YAFFS2 where tags are stored in the OOB. This patch changes the code so that oob_poi is always initialised to 0xFF to make sure no left over data is inadvertently written back to OOB data. Signed-off-by: Adam Thomson --- drivers/mtd/nand/nand_base.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 8c21b89..6bc7212 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1843,9 +1843,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, (chip->pagebuf << chip->page_shift) < (to + ops->len)) chip->pagebuf = -1; - /* If we're not given explicit OOB data, let it be 0xFF */ - if (likely(!oob)) - memset(chip->oob_poi, 0xff, mtd->oobsize); + /* + * Initialise to all 0xFF, to avoid the possibility of + * left over OOB data from a previous OOB read. + */ + memset(chip->oob_poi, 0xff, mtd->oobsize); while(1) { int bytes = mtd->writesize;