Message ID | 5899a02e.45ca240a.6c373.93c1@mx.google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hello Gerd, Ping... 2017-02-07 18:23 GMT+08:00 Li Qiang <liq3ea@gmail.com>: > From: Li Qiang <liqiang6-s@360.cn> > > The guest may builds an infinite loop with link eds. This patch > limit the number of linked ed to avoid this. > > Signed-off-by: Li Qiang <liqiang6-s@360.cn> > --- > hw/usb/hcd-ohci.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c > index c82a92f..4a63f3b 100644 > --- a/hw/usb/hcd-ohci.c > +++ b/hw/usb/hcd-ohci.c > @@ -42,6 +42,8 @@ > > #define OHCI_MAX_PORTS 15 > > +#define ED_LINK_LIMIT 4 > + > static int64_t usb_frame_time; > static int64_t usb_bit_time; > > @@ -1184,7 +1186,7 @@ static int ohci_service_ed_list(OHCIState *ohci, > uint32_t head, int completion) > uint32_t next_ed; > uint32_t cur; > int active; > - > + uint32_t link_cnt = 0; > active = 0; > > if (head == 0) > @@ -1199,6 +1201,11 @@ static int ohci_service_ed_list(OHCIState *ohci, > uint32_t head, int completion) > > next_ed = ed.next & OHCI_DPTR_MASK; > > + if (++link_cnt > ED_LINK_LIMIT) { > + ohci_die(ohci); > + return 0; > + } > + > if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) { > uint32_t addr; > /* Cancel pending packets for ED that have been paused. */ > -- > 1.8.3.1 > >
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index c82a92f..4a63f3b 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -42,6 +42,8 @@ #define OHCI_MAX_PORTS 15 +#define ED_LINK_LIMIT 4 + static int64_t usb_frame_time; static int64_t usb_bit_time; @@ -1184,7 +1186,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) uint32_t next_ed; uint32_t cur; int active; - + uint32_t link_cnt = 0; active = 0; if (head == 0) @@ -1199,6 +1201,11 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) next_ed = ed.next & OHCI_DPTR_MASK; + if (++link_cnt > ED_LINK_LIMIT) { + ohci_die(ohci); + return 0; + } + if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) { uint32_t addr; /* Cancel pending packets for ED that have been paused. */