@@ -565,6 +565,14 @@ void USBMSD::_read_next()
565
565
566
566
void USBMSD::memoryWrite (uint8_t *buf, uint16_t size)
567
567
{
568
+ // Max sized packets are required to be sent until the transfer is complete
569
+ MBED_ASSERT (_block_size % MAX_PACKET == 0 );
570
+ if ((size != MAX_PACKET) && (size != 0 )) {
571
+ _stage = ERROR;
572
+ endpoint_stall (_bulk_out);
573
+ return ;
574
+ }
575
+
568
576
if ((_addr + size) > _memory_size) {
569
577
size = _memory_size - _addr;
570
578
_stage = ERROR;
@@ -869,23 +877,25 @@ void USBMSD::memoryRead(void)
869
877
870
878
n = (_length > MAX_PACKET) ? MAX_PACKET : _length;
871
879
872
- if (( _addr + n) > _memory_size) {
873
- n = _memory_size - _addr;
880
+ if (_addr > ( _memory_size - n) ) {
881
+ n = _addr < _memory_size ? _memory_size - _addr : 0 ;
874
882
_stage = ERROR;
875
883
}
876
884
877
- // we read an entire block
878
- if (!(_addr % _block_size)) {
879
- disk_read (_page, _addr / _block_size, 1 );
880
- }
885
+ if (n > 0 ) {
886
+ // we read an entire block
887
+ if (!(_addr % _block_size)) {
888
+ disk_read (_page, _addr / _block_size, 1 );
889
+ }
881
890
882
- // write data which are in RAM
883
- _write_next (&_page[_addr % _block_size], MAX_PACKET);
891
+ // write data which are in RAM
892
+ _write_next (&_page[_addr % _block_size], MAX_PACKET);
884
893
885
- _addr += n;
886
- _length -= n;
894
+ _addr += n;
895
+ _length -= n;
887
896
888
- _csw.DataResidue -= n;
897
+ _csw.DataResidue -= n;
898
+ }
889
899
890
900
if (!_length || (_stage != PROCESS_CBW)) {
891
901
_csw.Status = (_stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
@@ -896,30 +906,37 @@ void USBMSD::memoryRead(void)
896
906
897
907
bool USBMSD::infoTransfer (void )
898
908
{
899
- uint32_t n ;
909
+ uint32_t addr_block ;
900
910
901
911
// Logical Block Address of First Block
902
- n = (_cbw.CB [2 ] << 24 ) | (_cbw.CB [3 ] << 16 ) | (_cbw.CB [4 ] << 8 ) | (_cbw.CB [5 ] << 0 );
912
+ addr_block = (_cbw.CB [2 ] << 24 ) | (_cbw.CB [3 ] << 16 ) | (_cbw.CB [4 ] << 8 ) | (_cbw.CB [5 ] << 0 );
913
+
914
+ _addr = addr_block * _block_size;
903
915
904
- _addr = n * _block_size;
916
+ if ((addr_block >= _block_count) || (_addr >= _memory_size)) {
917
+ _csw.Status = CSW_FAILED;
918
+ sendCSW ();
919
+ return false ;
920
+ }
905
921
922
+ uint32_t length_blocks = 0 ;
906
923
// Number of Blocks to transfer
907
924
switch (_cbw.CB [0 ]) {
908
925
case READ10:
909
926
case WRITE10:
910
927
case VERIFY10:
911
- n = (_cbw.CB [7 ] << 8 ) | (_cbw.CB [8 ] << 0 );
928
+ length_blocks = (_cbw.CB [7 ] << 8 ) | (_cbw.CB [8 ] << 0 );
912
929
break ;
913
930
914
931
case READ12:
915
932
case WRITE12:
916
- n = (_cbw.CB [6 ] << 24 ) | (_cbw.CB [7 ] << 16 ) | (_cbw.CB [8 ] << 8 ) | (_cbw.CB [9 ] << 0 );
933
+ length_blocks = (_cbw.CB [6 ] << 24 ) | (_cbw.CB [7 ] << 16 ) | (_cbw.CB [8 ] << 8 ) | (_cbw.CB [9 ] << 0 );
917
934
break ;
918
935
}
919
936
920
- _length = n * _block_size;
937
+ _length = length_blocks * _block_size;
921
938
922
- if (!_cbw.DataLength ) { // host requests no data
939
+ if (!_cbw.DataLength || !length_blocks || (length_blocks > _block_count - addr_block) || (_length > _memory_size - _addr)) { // host requests no data or wrong length
923
940
_csw.Status = CSW_FAILED;
924
941
sendCSW ();
925
942
return false ;
0 commit comments