Fix crash when dealing with 0000-0000 exfat UUID (!115)

GParted crashes when blkid doesn't provide the UUID of the exfat
partition and its serial has preceding zeroes (and it isn't mounted).

blkid doesn't report UUID if the serial number is 0000-0000 (a.k.a.
0x0).

Steps to reproduce:

    # truncate -s 4M /tmp/disk.img
    # losetup -f --show /tmp/disk.img
    /dev/loop0
    # mkfs.exfat /dev/loop0
    [...]
    exFAT format complete!
    # partprobe /dev/loop0
    # blkid /dev/loop0
    /dev/loop0: UUID="F7BF-ABFF" BLOCK_SIZE="512" TYPE="exfat" PTTYPE="dos"
    # exfatlabel /dev/loop0 -i 0x0
    exfatprogs version : 1.1.3
    New volume serial : 0x0
    # blkid /dev/loop0
    /dev/loop0: BLOCK_SIZE="512" TYPE="exfat" PTTYPE="dos"
    # gparted /dev/loop0
    GParted 1.3.1
    configuration --enable-libparted-dmraid --enable-online-resize
    libparted 3.4

    ** (gpartedbin:94926): ERROR **: 10:45:01.894:
    unhandled exception (type std::exception) in signal handler:
    what: basic_string::assign: __pos (which is 18446744073709551615) > this->size() (which is 3)

    Trace/breakpoint trap (core dumped)
    # losetup -d /dev/loop0; rm /tmp/disk.img

As blkid doesn't report exfat UUID 0000-0000 FS_Info cache can't report
it so exfat::read_uuid() is called.  Then `tune.exfat -i /dev/loop0` is
executed:

	# tune.exfat -i /dev/loop0
	exfatprogs version : 1.1.3
	volume serial : 0x0

And exfat::serial_to_blkid_uuid() is called with "0x0", which causes a
crash.  Fix by safely handling volume serial numbers of any length,
specifically shorter than 8 hexadecimal digits.

Closes !115 - Fix crash when dealing with 0000-0000 exfat UUID
This commit is contained in:
Marcin Zepp 2023-06-24 11:33:00 +02:00 committed by Mike Fleetwood
parent af684ade52
commit ac6528373f
1 changed files with 6 additions and 3 deletions

View File

@ -206,15 +206,18 @@ bool exfat::check_repair(const Partition& partition, OperationDetail& operationd
// Reformat exfat printed serial into the same format which blkid reports and GParted
// displays to users. Returns "" if source is not correctly formatted.
// E.g. "0x772ffe5d" -> "772F-FE5D"
// E.g. "0x772ffe5d" -> "772F-FE5D" or "0x0" -> "0000-0000"
Glib::ustring exfat::serial_to_blkid_uuid(const Glib::ustring& serial)
{
Glib::ustring verified_serial = Utils::regexp_label(serial, "^(0x[[:xdigit:]][[:xdigit:]]*)$");
if (verified_serial.empty())
return verified_serial;
Glib::ustring canonical_uuid = verified_serial.substr(2, 4).uppercase() + "-" +
verified_serial.substr(6, 4).uppercase();
// verified_serial is formatted with leading "0x" and 1 or more hex digits.
Glib::ustring temp = Glib::ustring(8, '0') + verified_serial.substr(2);
size_t len = temp.length();
Glib::ustring canonical_uuid = temp.substr(len - 8, 4).uppercase() + "-" +
temp.substr(len - 4, 4).uppercase();
return canonical_uuid;
}