@@ -572,6 +572,14 @@ void USBMSD::_read_next()
572572
573573void USBMSD::memoryWrite (uint8_t *buf, uint16_t size)
574574{
575+ // Max sized packets are required to be sent until the transfer is complete
576+ MBED_ASSERT (_block_size % MAX_PACKET == 0 );
577+ if ((size != MAX_PACKET) && (size != 0 )) {
578+ _stage = ERROR;
579+ endpoint_stall (_bulk_out);
580+ return ;
581+ }
582+
575583 if ((_addr + size) > _memory_size) {
576584 size = _memory_size - _addr;
577585 _stage = ERROR;
@@ -876,23 +884,25 @@ void USBMSD::memoryRead(void)
876884
877885 n = (_length > MAX_PACKET) ? MAX_PACKET : _length;
878886
879- if (( _addr + n) > _memory_size) {
880- n = _memory_size - _addr;
887+ if (_addr > ( _memory_size - n) ) {
888+ n = _addr < _memory_size ? _memory_size - _addr : 0 ;
881889 _stage = ERROR;
882890 }
883891
884- // we read an entire block
885- if (!(_addr % _block_size)) {
886- disk_read (_page, _addr / _block_size, 1 );
887- }
892+ if (n > 0 ) {
893+ // we read an entire block
894+ if (!(_addr % _block_size)) {
895+ disk_read (_page, _addr / _block_size, 1 );
896+ }
888897
889- // write data which are in RAM
890- _write_next (&_page[_addr % _block_size], MAX_PACKET);
898+ // write data which are in RAM
899+ _write_next (&_page[_addr % _block_size], MAX_PACKET);
891900
892- _addr += n;
893- _length -= n;
901+ _addr += n;
902+ _length -= n;
894903
895- _csw.DataResidue -= n;
904+ _csw.DataResidue -= n;
905+ }
896906
897907 if (!_length || (_stage != PROCESS_CBW)) {
898908 _csw.Status = (_stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
@@ -903,30 +913,37 @@ void USBMSD::memoryRead(void)
903913
904914bool USBMSD::infoTransfer (void )
905915{
906- uint32_t n ;
916+ uint32_t addr_block ;
907917
908918 // Logical Block Address of First Block
909- n = (_cbw.CB [2 ] << 24 ) | (_cbw.CB [3 ] << 16 ) | (_cbw.CB [4 ] << 8 ) | (_cbw.CB [5 ] << 0 );
919+ addr_block = (_cbw.CB [2 ] << 24 ) | (_cbw.CB [3 ] << 16 ) | (_cbw.CB [4 ] << 8 ) | (_cbw.CB [5 ] << 0 );
920+
921+ _addr = addr_block * _block_size;
910922
911- _addr = n * _block_size;
923+ if ((addr_block >= _block_count) || (_addr >= _memory_size)) {
924+ _csw.Status = CSW_FAILED;
925+ sendCSW ();
926+ return false ;
927+ }
912928
929+ uint32_t length_blocks = 0 ;
913930 // Number of Blocks to transfer
914931 switch (_cbw.CB [0 ]) {
915932 case READ10:
916933 case WRITE10:
917934 case VERIFY10:
918- n = (_cbw.CB [7 ] << 8 ) | (_cbw.CB [8 ] << 0 );
935+ length_blocks = (_cbw.CB [7 ] << 8 ) | (_cbw.CB [8 ] << 0 );
919936 break ;
920937
921938 case READ12:
922939 case WRITE12:
923- n = (_cbw.CB [6 ] << 24 ) | (_cbw.CB [7 ] << 16 ) | (_cbw.CB [8 ] << 8 ) | (_cbw.CB [9 ] << 0 );
940+ length_blocks = (_cbw.CB [6 ] << 24 ) | (_cbw.CB [7 ] << 16 ) | (_cbw.CB [8 ] << 8 ) | (_cbw.CB [9 ] << 0 );
924941 break ;
925942 }
926943
927- _length = n * _block_size;
944+ _length = length_blocks * _block_size;
928945
929- if (!_cbw.DataLength ) { // host requests no data
946+ if (!_cbw.DataLength || !length_blocks || (length_blocks > _block_count - addr_block) || (_length > _memory_size - _addr)) { // host requests no data or wrong length
930947 _csw.Status = CSW_FAILED;
931948 sendCSW ();
932949 return false ;
0 commit comments