DF-5381 / fix.diff
--- a/sys/bus/u4b/usb_busdma.c +++ b/sys/bus/u4b/usb_busdma.c @@ -86,6 +86,16 @@ if (pc->page_start) { /* Case 1 - something has been loaded into DMA */ + /* DF-5381: bound the offset by the loaded extent */ + if (offset >= (usb_frlength_t)(pc->page_offset_end - + pc->page_offset_buf)) { + res->buffer = NULL; + res->length = 0; +#if USB_HAVE_BUSDMA + res->physaddr = 0; +#endif + return; + } if (pc->buffer) { /* Case 1a - Kernel Virtual Address */ @@ -137,6 +147,9 @@ while (len != 0) { usbd_get_page(cache, offset, &buf_res); + if (buf_res.length == 0) + break; /* DF-5381: out of extent */ + if (buf_res.length > len) { buf_res.length = len; } @@ -166,6 +179,9 @@ while (len != 0) { usbd_get_page(cache, offset, &buf_res); + if (buf_res.length == 0) + return (EFAULT); /* DF-5381: out of extent */ + if (buf_res.length > len) { buf_res.length = len; } @@ -223,6 +239,11 @@ while (len != 0) { usbd_get_page(pc, pc_offset, &res); + if (res.length == 0) { + error = EFAULT; /* DF-5381: out of extent */ + break; + } + if (res.length > len) { res.length = len; } @@ -254,6 +275,9 @@ while (len != 0) { usbd_get_page(cache, offset, &res); + if (res.length == 0) + break; /* DF-5381: out of extent */ + if (res.length > len) { res.length = len; } @@ -283,6 +307,9 @@ while (len != 0) { usbd_get_page(cache, offset, &res); + if (res.length == 0) + return (EFAULT); /* DF-5381: out of extent */ + if (res.length > len) { res.length = len; } @@ -310,6 +337,9 @@ while (len != 0) { usbd_get_page(cache, offset, &res); + if (res.length == 0) + break; /* DF-5381: out of extent */ + if (res.length > len) { res.length = len; } |