aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2008-10-16 01:04:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 14:21:47 -0400
commitac0d86f5809598ddcd6bfa0ea8245ccc910e9eac (patch)
tree09d874a29ca655faefc5fc5cb637aebd1a732744
parent6722e45c2de622eaf5f26d370b9de19632ac7478 (diff)
block: sanitize invalid partition table entries
We currently follow blindly what the partition table lies about the disk, and let the kernel create block devices which can not be accessed. Trying to identify the device leads to kernel logs full of: sdb: rw=0, want=73392, limit=28800 attempt to access beyond end of device Here is an example of a broken partition table, where sda2 starts behind the end of the disk, and sdb3 is larger than the entire disk: Disk /dev/sdb: 14 MB, 14745600 bytes 1 heads, 29 sectors/track, 993 cylinders, total 28800 sectors Device Boot Start End Blocks Id System /dev/sdb1 29 7800 3886 83 Linux /dev/sdb2 37801 45601 3900+ 83 Linux /dev/sdb3 15602 73402 28900+ 83 Linux /dev/sdb4 23403 28796 2697 83 Linux The kernel creates these completely invalid devices, which can not be accessed, or may lead to other unpredictable failures: grep . /sys/class/block/sdb*/{start,size} /sys/class/block/sdb/size:28800 /sys/class/block/sdb1/start:29 /sys/class/block/sdb1/size:7772 /sys/class/block/sdb2/start:37801 /sys/class/block/sdb2/size:7801 /sys/class/block/sdb3/start:15602 /sys/class/block/sdb3/size:57801 /sys/class/block/sdb4/start:23403 /sys/class/block/sdb4/size:5394 With this patch, we ignore partitions which start behind the end of the disk, and limit partitions to the end of the disk if they pretend to be larger: grep . /sys/class/block/sdb*/{start,size} /sys/class/block/sdb/size:28800 /sys/class/block/sdb1/start:29 /sys/class/block/sdb1/size:7772 /sys/class/block/sdb3/start:15602 /sys/class/block/sdb3/size:13198 /sys/class/block/sdb4/start:23403 /sys/class/block/sdb4/size:5394 These warnings are printed to the kernel log: sdb: p2 ignored, start 37801 is behind the end of the disk sdb: p3 size 57801 limited to end of disk Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Cc: Herton Ronaldo Krzesinski <herton@mandriva.com.br> Cc: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/partitions/check.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 7408227c49c9..fbeb2f372a93 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -538,10 +538,23 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
538 sector_t from = state->parts[p].from; 538 sector_t from = state->parts[p].from;
539 if (!size) 539 if (!size)
540 continue; 540 continue;
541 if (from >= get_capacity(disk)) {
542 printk(KERN_WARNING
543 "%s: p%d ignored, start %llu is behind the end of the disk\n",
544 disk->disk_name, p, (unsigned long long) from);
545 continue;
546 }
541 if (from + size > get_capacity(disk)) { 547 if (from + size > get_capacity(disk)) {
548 /*
549 * we can not ignore partitions of broken tables
550 * created by for example camera firmware, but we
551 * limit them to the end of the disk to avoid
552 * creating invalid block devices
553 */
542 printk(KERN_WARNING 554 printk(KERN_WARNING
543 "%s: p%d exceeds device capacity\n", 555 "%s: p%d size %llu limited to end of disk\n",
544 disk->disk_name, p); 556 disk->disk_name, p, (unsigned long long) size);
557 size = get_capacity(disk) - from;
545 } 558 }
546 res = add_partition(disk, p, from, size, state->parts[p].flags); 559 res = add_partition(disk, p, from, size, state->parts[p].flags);
547 if (res) { 560 if (res) {