From f2cf7329971958c1a6b0bcc8926549bd50d6e6a2 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 1 May 2025 14:32:34 -0700 Subject: [PATCH] libpayload: usbmsc: Correctly deal with disks larger than 2TB Disks larger than 2TB (technically disks with more than 2^32 blocks, but for the common block size of 512 that comes out to 2TB) cannot represent their full amount of blocks in the SCSI READ_CAPACITY(10) command used by libpayload's USB mass storage driver. The entire driver isn't written to support block addresses larger than 32 bits anyway. The SCSI command has been designed in a clever way so that devices are supposed to return the maximum value (0xffffffff) if the actual value doesn't fit. However, our code adds one to the value (because it is actually the address of the last block, but we want to know the number of blocks). This makes it overflow back to 0 which is not great. This patch caps the result before incrementing it so that the overflow cannot occur, allowing us to at least access the first 2TB of super large USB sticks. Change-Id: Ic445923b7d588c4f523c4ed95a06291bc1969261 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/87506 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu --- payloads/libpayload/drivers/usb/usbmsc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/payloads/libpayload/drivers/usb/usbmsc.c b/payloads/libpayload/drivers/usb/usbmsc.c index 3f249d8bbb..762e644311 100644 --- a/payloads/libpayload/drivers/usb/usbmsc.c +++ b/payloads/libpayload/drivers/usb/usbmsc.c @@ -28,6 +28,7 @@ //#define USB_DEBUG #include +#include #include #include #include @@ -520,7 +521,7 @@ read_capacity(usbdev_t *dev) MSC_INST(dev)->numblocks = 0xffffffff; MSC_INST(dev)->blocksize = 512; } else { - MSC_INST(dev)->numblocks = ntohl(buf[0]) + 1; + MSC_INST(dev)->numblocks = MIN(ntohl(buf[0]), UINT_MAX - 1) + 1; MSC_INST(dev)->blocksize = ntohl(buf[1]); } usb_debug(" %d %d-byte sectors (%d MB)\n", MSC_INST(dev)->numblocks,