Skip to content

Commit ac105f5

Browse files
update USBMSD::infoTransfer implementation
Fix protects underlaying block device from out-of-bound read/writes - prevents the host from setting block device addres larger then block device size - prevents the host from setting wrong read/write lenght
1 parent da9f85b commit ac105f5

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

drivers/source/usb/USBMSD.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -903,30 +903,37 @@ void USBMSD::memoryRead(void)
903903

904904
bool USBMSD::infoTransfer(void)
905905
{
906-
uint32_t n;
906+
uint32_t addr_block;
907907

908908
// Logical Block Address of First Block
909-
n = (_cbw.CB[2] << 24) | (_cbw.CB[3] << 16) | (_cbw.CB[4] << 8) | (_cbw.CB[5] << 0);
909+
addr_block = (_cbw.CB[2] << 24) | (_cbw.CB[3] << 16) | (_cbw.CB[4] << 8) | (_cbw.CB[5] << 0);
910+
911+
_addr = addr_block * _block_size;
910912

911-
_addr = n * _block_size;
913+
if ((addr_block >= _block_count) || (_addr >= _memory_size)) {
914+
_csw.Status = CSW_FAILED;
915+
sendCSW();
916+
return false;
917+
}
912918

919+
uint32_t length_blocks = 0;
913920
// Number of Blocks to transfer
914921
switch (_cbw.CB[0]) {
915922
case READ10:
916923
case WRITE10:
917924
case VERIFY10:
918-
n = (_cbw.CB[7] << 8) | (_cbw.CB[8] << 0);
925+
length_blocks = (_cbw.CB[7] << 8) | (_cbw.CB[8] << 0);
919926
break;
920927

921928
case READ12:
922929
case WRITE12:
923-
n = (_cbw.CB[6] << 24) | (_cbw.CB[7] << 16) | (_cbw.CB[8] << 8) | (_cbw.CB[9] << 0);
930+
length_blocks = (_cbw.CB[6] << 24) | (_cbw.CB[7] << 16) | (_cbw.CB[8] << 8) | (_cbw.CB[9] << 0);
924931
break;
925932
}
926933

927-
_length = n * _block_size;
934+
_length = length_blocks * _block_size;
928935

929-
if (!_cbw.DataLength) { // host requests no data
936+
if (!_cbw.DataLength || !length_blocks || (length_blocks > _block_count - addr_block) || (_length > _memory_size - _addr)) { // host requests no data or wrong length
930937
_csw.Status = CSW_FAILED;
931938
sendCSW();
932939
return false;

0 commit comments

Comments
 (0)