[dm-devel] [PATCH udm] Fix oops on zero-length tables
Christophe Saout
christophe at saout.de
Wed Dec 31 18:27:01 UTC 2003
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";
More information about the dm-devel
mailing list