From patchwork Tue Aug 4 01:44:52 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 39042 X-Patchwork-Delegate: agk@redhat.com Received: from hormel.redhat.com (hormel1.redhat.com [209.132.177.33]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n741iumi011953 for ; Tue, 4 Aug 2009 01:44:56 GMT Received: from listman.util.phx.redhat.com (listman.util.phx.redhat.com [10.8.4.110]) by hormel.redhat.com (Postfix) with ESMTP id 30075619E18; Mon, 3 Aug 2009 21:44:56 -0400 (EDT) Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by listman.util.phx.redhat.com (8.13.1/8.13.1) with ESMTP id n741ir1G029155 for ; Mon, 3 Aug 2009 21:44:53 -0400 Received: from hs20-bc2-1.build.redhat.com (hs20-bc2-1.build.redhat.com [10.10.28.34]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n741irVm030265; Mon, 3 Aug 2009 21:44:53 -0400 Received: from hs20-bc2-1.build.redhat.com (localhost.localdomain [127.0.0.1]) by hs20-bc2-1.build.redhat.com (8.13.1/8.13.1) with ESMTP id n741irEc007071; Mon, 3 Aug 2009 21:44:53 -0400 Received: from localhost (mpatocka@localhost) by hs20-bc2-1.build.redhat.com (8.13.1/8.13.1/Submit) with ESMTP id n741iqqO007065; Mon, 3 Aug 2009 21:44:52 -0400 X-Authentication-Warning: hs20-bc2-1.build.redhat.com: mpatocka owned process doing -bs Date: Mon, 3 Aug 2009 21:44:52 -0400 (EDT) From: Mikulas Patocka X-X-Sender: mpatocka@hs20-bc2-1.build.redhat.com To: dm-devel@redhat.com In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 X-loop: dm-devel@redhat.com Cc: Alasdair G Kergon Subject: [dm-devel] [PATCH 4/4] Check on-disk chunk size. X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.5 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com Check on-disk chunk size. The previous code blindly used the chunk size stored on disk. This is wrong because it can lead to a crash if the disk storage is corrupted. See https://bugzilla.redhat.com/show_bug.cgi?id=461506 This code passes on-disk size through similar checks as size specified on the table argument line, thus it won't allow to use bogus values (such as zero, in case of that bug). Signed-off-by: Mikulas Patocka --- drivers/md/dm-snap-persistent.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel Index: linux-2.6.31-rc5-devel/drivers/md/dm-snap-persistent.c =================================================================== --- linux-2.6.31-rc5-devel.orig/drivers/md/dm-snap-persistent.c 2009-08-04 03:20:11.000000000 +0200 +++ linux-2.6.31-rc5-devel/drivers/md/dm-snap-persistent.c 2009-08-04 03:24:16.000000000 +0200 @@ -283,6 +283,7 @@ static int read_header(struct pstore *ps struct disk_header *dh; chunk_t chunk_size; int chunk_size_supplied = 1; + char *chunk_err; /* * Use default chunk size (or hardsect_size, if larger) if none supplied @@ -326,20 +327,23 @@ static int read_header(struct pstore *ps ps->version = le32_to_cpu(dh->version); chunk_size = le32_to_cpu(dh->chunk_size); - if (!chunk_size_supplied || ps->store->chunk_size == chunk_size) + if (ps->store->chunk_size == chunk_size) return 0; - DMWARN("chunk size %llu in device metadata overrides " - "table chunk size of %llu.", - (unsigned long long)chunk_size, - (unsigned long long)ps->store->chunk_size); + if (chunk_size_supplied) + DMWARN("chunk size %llu in device metadata overrides " + "table chunk size of %llu.", + (unsigned long long)chunk_size, + (unsigned long long)ps->store->chunk_size); /* We had a bogus chunk_size. Fix stuff up. */ free_area(ps); - ps->store->chunk_size = chunk_size; - ps->store->chunk_mask = chunk_size - 1; - ps->store->chunk_shift = ffs(chunk_size) - 1; + r = dm_exception_store_set_chunk_size(ps->store, chunk_size, &chunk_err); + if (r) { + DMERR("invalid on-disk chunk size %llu: %s.", (unsigned long long)chunk_size, chunk_err); + return r; + } r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), ps->io_client);