Bug 1351964 - kpartx: avoid MSDOS recursive partition tables via the EBR
Summary: kpartx: avoid MSDOS recursive partition tables via the EBR
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: device-mapper-multipath
Version: 7.4
Hardware: All
OS: All
unspecified
low
Target Milestone: rc
: ---
Assignee: Ben Marzinski
QA Contact: Lin Li
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-07-01 09:12 UTC by Cedric Buissart 🐶
Modified: 2017-08-01 16:34 UTC (History)
7 users (show)

Fixed In Version: device-mapper-multipath-0.4.9-101.el7
Doc Type: No Doc Update
Doc Text:
undefined
Clone Of:
Environment:
Last Closed: 2017-08-01 16:34:26 UTC
Target Upstream Version:


Attachments (Terms of Use)
Prevent recursive MSDOS partition table (514 bytes, patch)
2016-07-01 09:12 UTC, Cedric Buissart 🐶
no flags Details | Diff


Links
System ID Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2017:1961 normal SHIPPED_LIVE device-mapper-multipath bug fix and enhancement update 2017-08-01 17:56:09 UTC

Description Cedric Buissart 🐶 2016-07-01 09:12:18 UTC
Created attachment 1174848 [details]
Prevent recursive MSDOS partition table

Description of problem:

During analysis of a similar bug in libblkid, I found out that kpartx could create up to MAXSLICES (256) partitions in case an extended partition table points to itself.

Version-Release number of selected component (if applicable): probably all (including upstream)


How reproducible: easy


Steps to Reproduce:
1. create a device with a recursive partition table :
# truncate -s 1M device.disk
# (echo x; echo c; echo 42; echo r; echo n; echo p; echo 1; echo 1; echo 1; echo n; echo e; echo 2; echo 2; echo 2; echo w) | fdisk device.disk
# dd if=/dev/zero bs=1c count=4 conv=notrunc seek=$((0x1d6)) of=./device.disk

Note: the dd will modify the LBA start value of the extended partition table to 0 (the partition table itself).

2. use this as a block device
# losetup -f ./device.disk

3. enjoy!
# kpartx -a /dev/loop0

Actual results:
MAXSLICES (256) block devices will be created. But we probably do not want that many.

Expected results:
The number of partitions is technically less than that.


Additional info:

parted works around this behavior in a similar manner :
http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/labels/dos.c#n1025

Though kpartx does not loop forever thanks to MAXSLICES, it might still be better to prevent recursion in the first place.

Comment 2 Ben Marzinski 2016-09-06 21:41:49 UTC
This bug arrived too late for rhel-7.3.

Comment 3 Ben Marzinski 2017-02-16 19:32:46 UTC
Patch applied. Thanks.

Comment 5 Lin Li 2017-06-03 10:43:44 UTC
Reproduced on device-mapper-multipath-0.4.9-99.el7
1.[root@storageqe-73 ~]# rpm -qa | grep multipath
device-mapper-multipath-0.4.9-99.el7.x86_64
device-mapper-multipath-libs-0.4.9-99.el7.x86_64
2.[root@storageqe-73 ~]# truncate -s 1M device.disk
3.[root@storageqe-73 ~]# (echo x; echo c; echo 42; echo r; echo n; echo p; echo 1; echo 1; echo 1; echo n; echo e; echo 2; echo 2; echo 2; echo w) | fdisk device.disk
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x90548776.
You must set cylinders.
You can do this from the extra functions menu.

Command (m for help): 
Expert command (m for help): Number of cylinders (1-1048576): 
Expert command (m for help): 
Command (m for help): Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): Partition number (1-4, default 1): First sector (1-2047, default 1): Last sector, +sectors or +size{K,M,G} (1-2047, default 2047): Partition 1 of type Linux and of size 512 B is set

Command (m for help): Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): Partition number (2-4, default 2): First sector (2-2047, default 2): Last sector, +sectors or +size{K,M,G} (2-2047, default 2047): Partition 2 of type Extended and of size 512 B is set

Command (m for help): The partition table has been altered!

Syncing disks.
4.[root@storageqe-73 ~]# dd if=/dev/zero bs=1c count=4 conv=notrunc seek=$((0x1d6)) of=./device.disk
4+0 records in
4+0 records out
4 bytes (4 B) copied, 0.00013678 s, 29.2 kB/s
5.[root@storageqe-73 ~]# losetup -f ./device.disk
6.[root@storageqe-73 ~]# kpartx -a /dev/loop0
dos_extd_partition: too many slices  


Verified on device-mapper-multipath-0.4.9-111.el7
1. [root@storageqe-73 ~]# rpm -qa | grep multipath
device-mapper-multipath-devel-0.4.9-111.el7.x86_64
device-mapper-multipath-libs-0.4.9-111.el7.x86_64
device-mapper-multipath-0.4.9-111.el7.x86_64
device-mapper-multipath-sysvinit-0.4.9-111.el7.x86_64
device-mapper-multipath-debuginfo-0.4.9-111.el7.x86_64
2. [root@storageqe-73 ~]# truncate -s 1M device.disk
3. [root@storageqe-73 ~]# (echo x; echo c; echo 42; echo r; echo n; echo p; echo 1; echo 1; echo 1; echo n; echo e; echo 2; echo 2; echo 2; echo w) | fdisk device.disk
You must set cylinders.
You can do this from the extra functions menu.
Bad offset in primary extended partition
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): 
Expert command (m for help): Number of cylinders (1-1048576): 
Expert command (m for help): 
Command (m for help): Partition type:
   p   primary (2 primary, 0 extended, 2 free)
   e   extended
Select (default p): Partition number (3,4, default 3): Value out of range.
Partition number (3,4, default 3): Value out of range.
Partition number (3,4, default 3): Value out of range.
Partition number (3,4, default 3): Partition number (3,4, default 3): Partition number (3,4, default 3): Value out of range.
Partition number (3,4, default 3): Value out of range.
Partition number (3,4, default 3): Value out of range.
Partition number (3,4, default 3): Partition number (3,4, default 3): 

4. [root@storageqe-73 ~]# dd if=/dev/zero bs=1c count=4 conv=notrunc seek=$((0x1d6)) of=./device.disk
4+0 records in
4+0 records out
4 bytes (4 B) copied, 0.000141003 s, 28.4 kB/s

5. [root@storageqe-73 ~]# losetup -f ./device.disk
6. [root@storageqe-73 ~]# kpartx -a /dev/loop0  
7. [root@storageqe-73 ~]# echo $?
0

Comment 6 errata-xmlrpc 2017-08-01 16:34:26 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2017:1961


Note You need to log in before you can comment on or make changes to this bug.