@@ -572,6 +572,14 @@ void USBMSD::_read_next()
572
572
573
573
void USBMSD::memoryWrite (uint8_t *buf, uint16_t size)
574
574
{
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
+
575
583
if ((_addr + size) > _memory_size) {
576
584
size = _memory_size - _addr;
577
585
_stage = ERROR;
@@ -876,23 +884,25 @@ void USBMSD::memoryRead(void)
876
884
877
885
n = (_length > MAX_PACKET) ? MAX_PACKET : _length;
878
886
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 ;
881
889
_stage = ERROR;
882
890
}
883
891
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
+ }
888
897
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);
891
900
892
- _addr += n;
893
- _length -= n;
901
+ _addr += n;
902
+ _length -= n;
894
903
895
- _csw.DataResidue -= n;
904
+ _csw.DataResidue -= n;
905
+ }
896
906
897
907
if (!_length || (_stage != PROCESS_CBW)) {
898
908
_csw.Status = (_stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
@@ -903,30 +913,37 @@ void USBMSD::memoryRead(void)
903
913
904
914
bool USBMSD::infoTransfer (void )
905
915
{
906
- uint32_t n ;
916
+ uint32_t addr_block ;
907
917
908
918
// 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;
910
922
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
+ }
912
928
929
+ uint32_t length_blocks = 0 ;
913
930
// Number of Blocks to transfer
914
931
switch (_cbw.CB [0 ]) {
915
932
case READ10:
916
933
case WRITE10:
917
934
case VERIFY10:
918
- n = (_cbw.CB [7 ] << 8 ) | (_cbw.CB [8 ] << 0 );
935
+ length_blocks = (_cbw.CB [7 ] << 8 ) | (_cbw.CB [8 ] << 0 );
919
936
break ;
920
937
921
938
case READ12:
922
939
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 );
924
941
break ;
925
942
}
926
943
927
- _length = n * _block_size;
944
+ _length = length_blocks * _block_size;
928
945
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
930
947
_csw.Status = CSW_FAILED;
931
948
sendCSW ();
932
949
return false ;
0 commit comments