@@ -731,7 +731,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
731
731
}
732
732
733
733
start_offset = iso_td .offset [relative_frame_number ];
734
- next_offset = iso_td .offset [relative_frame_number + 1 ];
734
+ if (relative_frame_number < frame_count ) {
735
+ next_offset = iso_td .offset [relative_frame_number + 1 ];
736
+ } else {
737
+ next_offset = iso_td .be ;
738
+ }
735
739
736
740
if (!(OHCI_BM (start_offset , TD_PSW_CC ) & 0xe ) ||
737
741
((relative_frame_number < frame_count ) &&
@@ -764,7 +768,12 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
764
768
}
765
769
} else {
766
770
/* Last packet in the ISO TD */
767
- end_addr = iso_td .be ;
771
+ end_addr = next_offset ;
772
+ }
773
+
774
+ if (start_addr > end_addr ) {
775
+ trace_usb_ohci_iso_td_bad_cc_overrun (start_addr , end_addr );
776
+ return 1 ;
768
777
}
769
778
770
779
if ((start_addr & OHCI_PAGE_MASK ) != (end_addr & OHCI_PAGE_MASK )) {
@@ -773,6 +782,9 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
773
782
} else {
774
783
len = end_addr - start_addr + 1 ;
775
784
}
785
+ if (len > sizeof (ohci -> usb_buf )) {
786
+ len = sizeof (ohci -> usb_buf );
787
+ }
776
788
777
789
if (len && dir != OHCI_TD_DIR_IN ) {
778
790
if (ohci_copy_iso_td (ohci , start_addr , end_addr , ohci -> usb_buf , len ,
@@ -975,8 +987,16 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
975
987
if ((td .cbp & 0xfffff000 ) != (td .be & 0xfffff000 )) {
976
988
len = (td .be & 0xfff ) + 0x1001 - (td .cbp & 0xfff );
977
989
} else {
990
+ if (td .cbp > td .be ) {
991
+ trace_usb_ohci_iso_td_bad_cc_overrun (td .cbp , td .be );
992
+ ohci_die (ohci );
993
+ return 1 ;
994
+ }
978
995
len = (td .be - td .cbp ) + 1 ;
979
996
}
997
+ if (len > sizeof (ohci -> usb_buf )) {
998
+ len = sizeof (ohci -> usb_buf );
999
+ }
980
1000
981
1001
pktlen = len ;
982
1002
if (len && dir != OHCI_TD_DIR_IN ) {
0 commit comments