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

[dm-devel] [PATCH udm] Fix oops on zero-length tables



Hi!

echo 0 0 linear /dev/vg/play 0 | dmsetup create test

produces the following oops:

Unable to handle kernel paging request at virtual address d2b56000
printing eip:
c02ff6d8
*pde = 0fd4f067
*pte = 00000000
Oops: 0000 [#1]
CPU:    0
EIP:    0060:[<c02ff6d8>]    Not tainted
EFLAGS: 00210202
EIP is at dm_table_get_size+0x18/0x20
eax: d2b56000   ebx: c20e89c0   ecx: c7ea39e0   edx: 00000001
esi: c043bee0   edi: c20e89c0   ebp: c21fdf24   esp: c21fdf24
ds: 007b   es: 007b   ss: 0068
Process dmconvert (pid: 6835, threadinfo=c21fc000 task=c1616060)
Stack: c21fdf38 c02fe118 c7ea39e0 00000042 c7ea39e0 c21fdf5c c030170c c20e89c0
       00000000 c7ea39e0 00000000 c21fc000 00000000 00000006 c21fdf8c c0302786
       d2b4d000 00004000 00000134 d2b4d000 c21fc000 c0301770 d2b4d000 c134fd06
Call Trace:
[<c02fe118>] dm_resume+0x68/0xb0
[<c030170c>] do_resume+0x14c/0x1b0
[<c0302786>] ctl_ioctl+0xe6/0x180
[<c0301770>] dev_suspend+0x0/0x20
[<c016b610>] sys_ioctl+0x100/0x2a0
[<c010b3b9>] sysenter_past_esp+0x52/0x71

Code: 8b 44 90 fc 40 5d c3 90 55 89 e5 8b 4d 08 8b 55 0c 3b 91 88

What happens?

In __bind size = dm_table_get_size(t) correctly returns zero, the
reference isn't gotten and do_resume destroys the table, but the
map already got set.

diff -Nur linux.orig/drivers/md/dm.c linux/drivers/md/dm.c
--- linux.orig/drivers/md/dm.c	2004-01-01 00:55:31.927764144 +0100
+++ linux/drivers/md/dm.c	2004-01-01 01:06:55.736809368 +0100
@@ -745,13 +745,13 @@
 {
 	request_queue_t *q = md->queue;
 	sector_t size;
-	md->map = t;
 
 	size = dm_table_get_size(t);
 	__set_size(md->disk, size);
 	if (size == 0)
 		return 0;
 
+	md->map = t;
 	dm_table_event_callback(md->map, event_callback, md);
 
 	dm_table_get(t);


I don't think that zero targets should be allowed, so this should
probably also be checked:

diff -Nur linux.orig/drivers/md/dm-table.c linux/drivers/md/dm-table.c
--- linux.orig/drivers/md/dm-table.c	2004-01-01 00:56:35.393115944 +0100
+++ linux/drivers/md/dm-table.c	2004-01-01 00:56:44.717698392 +0100
@@ -655,6 +655,11 @@
 	memset(tgt, 0, sizeof(*tgt));
 	set_default_limits(&tgt->limits);
 
+	if (!len) {
+		tgt->error = "zero-length target";
+		return -EINVAL;
+	}
+
 	tgt->type = dm_get_target_type(type);
 	if (!tgt->type) {
 		tgt->error = "unknown target type";




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