From ac6528373f81b3d7652b9d09f1347277f59bde82 Mon Sep 17 00:00:00 2001 From: Marcin Zepp Date: Sat, 24 Jun 2023 11:33:00 +0200 Subject: [PATCH] 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 --- src/exfat.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/exfat.cc b/src/exfat.cc index 459edfc3..39edcdb1 100644 --- a/src/exfat.cc +++ b/src/exfat.cc @@ -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; }