Bug 1344482

Summary: util-linux fails valid_pmbr() size checks if device is > 2.14TB, Device label type: dos instead of gpt
Product: Red Hat Enterprise Linux 7 Reporter: Dwight (Bud) Brown <bubrown>
Component: util-linuxAssignee: Karel Zak <kzak>
Status: CLOSED ERRATA QA Contact: qe-baseos-daemons
Severity: unspecified Docs Contact:
Priority: high    
Version: 7.2CC: mgandhi, todoleza
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: util-linux-2.23.2-31.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-11-03 21:27:27 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
gpt check patch none

Description Dwight (Bud) Brown 2016-06-09 19:12:55 UTC
Description of problem:
In using fdisk against disks with GUID/GPT partitioning, expecting to see

Command (m for help): p

Disk /dev/sde: 3298.5 GB, 3298534883328 bytes, 6442450944 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 33550336 bytes
Disk label type: gpt
Disk identifier: 0x00000000

...and will when the disk is <2.14TB (so technically wouldn't need to use 
   GUID/GPT partitioning).
   but when disks are >2.14TB in size, it displays instead:

Command (m for help): p

Disk /dev/sde: 3298.5 GB, 3298534883328 bytes, 6442450944 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 33550336 bytes
Disk label type: dos  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Disk identifier: 0x000000000




Version-Release number of selected component (if applicable):
util-linux-2.23.2-26.el7_2.2

How reproducible:
100%

Steps to Reproduce:
1. parted /dev/sdX mklabel gpt
2. fdisk -uc /dev/sdX
3.

Actual results:
Disk label type: dos

Expected results:
Disk label type: gpt

Additional info:

        /*
         * Protective MBRs take up the lesser of the whole disk
         * or 2 TiB (32bit LBA), ignoring the rest of the disk.
         *
         * Hybrid MBRs do not necessarily comply with this.
         */
        if (ret == GPT_MBR_PROTECTIVE) {
                if (le32_to_cpu(pmbr->partition_record[0].size_in_lba) !=
                    min((uint32_t) cxt->total_sectors - 1, 0xFFFFFFFF))
                        ret = 0;
        }


Will compute result in ret=0 when disk is > 2.14TB.  For example, a 3TB disk has total sectors of 0x180000000, min() function above ends up as:

min( 0x80000000-1,  0xFFFFFFFF )
min( 0x7FFFFFFF  ,  0xFFFFFFFF ) = 0x7FFFFFFF 

Disks > 2.14TB will have the size_in_lba limited to 0xFFFFFFFF (UINT_MAX), resulting in the above if ... statement being true and ret=0 is returned when
it shouldn't be.  The correct code would be something like:


(uint32_t)min( cxt->total_sectors - 1, 0xFFFFFFFFULL )



The above min() as above is used in both valid_pmbr() and gpt_mknew_pmbr(), possibly others.  

Current code essentially looks like it computes:
   (total_sectors-1) & 0xFFFFFFFF 
vs comparing total_sectors-1 to UINT_MAX and then truncating the results of the comparison.

Note that while physical disks are often in whole TiB size, provisioned disks in storage can be odd sizes like total_sectors = 0500005C00 which would end up with a reported min of 0x00005BFF with the current code.

Comment 2 Dwight (Bud) Brown 2016-06-10 13:02:39 UTC
Created attachment 1166630 [details]
gpt check patch

attached patch tested, resulted in expected output:

fdisk w/attached patch:

# fdisk -uc /dev/sde
WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.  <<<<<<<<<<<<<<<<[1]
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): p

Disk /dev/sde: 3298.5 GB, 3298534883328 bytes, 6442450944 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 33550336 bytes
Disk label type: gpt  <<<<<<<<<<<<<<<< [2]


#         Start          End    Size  Type            Name
<<<<<< [3]

[1] is output at end of gpt_label_probe(), so it detects GUID/GPT correctly
[2] and displays gpt
[3] and currently this gpt table is empty [just did parted mklabel on disk]

Comment 8 errata-xmlrpc 2016-11-03 21:27:27 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://rhn.redhat.com/errata/RHSA-2016-2605.html