[dm-devel] [PATCH] dm-table.c::dm_table_create

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In dm-table.c::dm_create_table(), the size of the array allocated for t->highs 
*must* be a multiple of KEYS_PER_NODE. If not, dm-table.c::high() may index 
off the end of an array, causing fields in t->index to be initialized 
incorrectly, which will eventually lead to I/O errors or segfaults due to bad 
return pointers from dm_table_find_target().

To verify this, use dmsetup to create exactly 12 small linear devices, each 10 
sectors long. Then create another device that concatenates all 12 of these 
devices together. Do a simple dd to this device and it will either cause I/O 
errors, or possibly segfault the kernel.

Here are the mapping files I used for my test:

Filename	Mapping
child00	0 10 linear /dev/hdd9 0
child01	0 10 linear /dev/hdd9 10
child02	0 10 linear /dev/hdd9 20
child03	0 10 linear /dev/hdd9 30
child04	0 10 linear /dev/hdd9 40
child05	0 10 linear /dev/hdd9 50
child06	0 10 linear /dev/hdd9 60
child07	0 10 linear /dev/hdd9 70
child08	0 10 linear /dev/hdd9 80
child09	0 10 linear /dev/hdd9 90
child10	0 10 linear /dev/hdd9 100
child11	0 10 linear /dev/hdd9 110

link		0 10 linear /dev/mapper/child00 0
		10 10 linear /dev/mapper/child01 0
		20 10 linear /dev/mapper/child02 0
		30 10 linear /dev/mapper/child03 0
		40 10 linear /dev/mapper/child04 0
		50 10 linear /dev/mapper/child05 0
		60 10 linear /dev/mapper/child06 0
		70 10 linear /dev/mapper/child07 0
		80 10 linear /dev/mapper/child08 0
		90 10 linear /dev/mapper/child09 0
		100 10 linear /dev/mapper/child10 0
		110 10 linear /dev/mapper/child11 0


dd if=/dev/zero of=/dev/mapper/link bs=512

This command fails at sector 80 on my machine. The test requires exactly 12 or 
13 devices in the "link" device.


Here are two patches to fix the bug. The first is against 
device-mapper-1.00.05, and the second is against Joe's 2.4.23-pre7-dm3 
patchset (which have different versions of dm_table_create).

-- 
Kevin Corry
kevcorry@xxxxxxxxxx
http://evms.sourceforge.net/

--- a/drivers/md/dm-table.c	1 Oct 2003 21:48:54 -0000
+++ b/drivers/md/dm-table.c	24 Oct 2003 17:20:08 -0000
@@ -162,6 +162,8 @@
 	if (!num_targets)
 		num_targets = KEYS_PER_NODE;
 
+	num_targets = dm_round_up(num_targets, KEYS_PER_NODE);
+
 	if (alloc_targets(t, num_targets)) {
 		kfree(t);
 		t = NULL;
--- a/drivers/md/dm-table.c	2003-10-24 13:21:29.000000000 -0500
+++ b/drivers/md/dm-table.c	2003-10-24 13:31:55.000000000 -0500
@@ -123,6 +123,7 @@
 	INIT_LIST_HEAD(&t->devices);
 	atomic_set(&t->holders, 1);
 
+	num_targets = dm_round_up(num_targets, KEYS_PER_NODE);
 
 	/* allocate both the target array and offset array at once */
 	t->highs = (sector_t *) vcalloc(sizeof(struct dm_target) +

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux