On Mon, Apr 13, 2020 at 12:44:54PM -0600, Theo de Raadt wrote:
> Then you need to look at why this crazy value is composed here in this
> loop:
> 
>         actlen = 0;
>         for (sqtd = ex->sqtdstart; sqtd != NULL; sqtd = sqtd->nextqtd) {
>                 usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
>                     BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
>                 nstatus = letoh32(sqtd->qtd.qtd_status);
>                 if (nstatus & EHCI_QTD_ACTIVE)
>                         break;
> 
>                 status = nstatus;
>                 /* halt is ok if descriptor is last, and complete */
>                 if (sqtd->qtd.qtd_next == htole32(EHCI_LINK_TERMINATE) &&
>                     EHCI_QTD_GET_BYTES(status) == 0)
>                         status &= ~EHCI_QTD_HALTED;
>                 if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
>                         actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
>       }

But I just described that in one of my previous emails few minutes ago.

In my diff I'm using second loop of the same code, but I guess I can
provide more surgurucal diff to be more explicit. What I wrote in my
previous email can be written also as follows:

        actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);

In above equation, on first for loop iteration:

actlen is 0
EHCI_QTD_GET_BYTES(status) is 16000
sqtd->len is 8

actlen += 8 - 1600;

Which results of actlen being 4294951304, from that moment we are
heading to kernel panic.

-- 
Regards,
 Mikolaj

Reply via email to