Bug 1351964

Summary: kpartx: avoid MSDOS recursive partition tables via the EBR
Product: Red Hat Enterprise Linux 7 Reporter: Cedric Buissart <cbuissar>
Component: device-mapper-multipathAssignee: Ben Marzinski <bmarzins>
Status: CLOSED ERRATA QA Contact: Lin Li <lilin>
Severity: low Docs Contact:
Priority: unspecified    
Version: 7.4CC: agk, bmarzins, heinzm, lilin, msnitzer, prajnoha, yizhan
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: device-mapper-multipath-0.4.9-101.el7 Doc Type: No Doc Update
Doc Text:
undefined
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-08-01 16:34:26 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Prevent recursive MSDOS partition table none

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