diff options
author | Francois Toguo <francois.toguo.fotso@intel.com> | 2019-03-27 10:30:20 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2019-04-09 17:25:41 +0000 |
commit | 651d8dd4f6562e1176d87b7dfe7210507a622f55 (patch) | |
tree | d8f20ab37c5194bb04854ae3afe44f1c626cea7f /payloads/libpayload/drivers/usb/ohci.c | |
parent | e0c181d48790be12b469b175bf4d9931a8c79fa1 (diff) | |
download | coreboot-651d8dd4f6562e1176d87b7dfe7210507a622f55.tar.xz |
libpayload: Fix potential NULL pointer dereference
Found-by: Klockwork
BUG=NONE
TEST=Boot to OS on GLK Sparky
Signed-off-by: Francois Toguo <francois.toguo.fotso@intel.com>
Change-Id: I9d4636f0429de829e746909492c2f543026a02ac
Reviewed-on: https://review.coreboot.org/c/coreboot/+/32083
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lijian Zhao <lijian.zhao@intel.com>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'payloads/libpayload/drivers/usb/ohci.c')
-rw-r--r-- | payloads/libpayload/drivers/usb/ohci.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/payloads/libpayload/drivers/usb/ohci.c b/payloads/libpayload/drivers/usb/ohci.c index 1964689b41..ecd1084005 100644 --- a/payloads/libpayload/drivers/usb/ohci.c +++ b/payloads/libpayload/drivers/usb/ohci.c @@ -212,6 +212,8 @@ ohci_init (unsigned long physical_bar) udelay (10); /* at most 10us for reset to complete. State must be set to Operational within 2ms (5.1.1.4) */ OHCI_INST (controller)->opreg->HcFmInterval = interval; OHCI_INST (controller)->hcca = dma_memalign(256, 256); + if (!OHCI_INST(controller)->hcca) + fatal("Not enough DMA memory for OHCI HCCA.\n"); memset((void*)OHCI_INST (controller)->hcca, 0, 256); if (dma_initialized()) { @@ -223,6 +225,8 @@ ohci_init (unsigned long physical_bar) /* Initialize interrupt table. */ u32 *const intr_table = OHCI_INST(controller)->hcca->HccaInterruptTable; ed_t *const periodic_ed = dma_memalign(sizeof(ed_t), sizeof(ed_t)); + if (!periodic_ed) + fatal("Not enough DMA memory for OHCI interrupt table.\n"); memset((void *)periodic_ed, 0, sizeof(*periodic_ed)); for (i = 0; i < 32; ++i) intr_table[i] = virt_to_phys(periodic_ed); @@ -378,6 +382,8 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, /* First TD. */ td_t *const first_td = (td_t *)dma_memalign(sizeof(td_t), sizeof(td_t)); + if (!first_td) + fatal("Not enough DMA memory for OHCI first TD in buffer.\n"); memset((void *)first_td, 0, sizeof(*first_td)); cur = first_td; @@ -392,6 +398,8 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, while (pages > 0) { /* One more TD. */ td_t *const next = (td_t *)dma_memalign(sizeof(td_t), sizeof(td_t)); + if (!next) + fatal("Not enough DMA memory for OHCI new page.\n"); memset((void *)next, 0, sizeof(*next)); /* Linked to the previous. */ cur->next_td = virt_to_phys(next); @@ -426,6 +434,8 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, /* One more TD. */ td_t *const next_td = (td_t *)dma_memalign(sizeof(td_t), sizeof(td_t)); + if (!next_td) + fatal("Not enough DMA memory for OHCI additional TD.\n"); memset((void *)next_td, 0, sizeof(*next_td)); /* Linked to the previous. */ cur->next_td = virt_to_phys(next_td); @@ -441,12 +451,16 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, /* Final dummy TD. */ td_t *const final_td = (td_t *)dma_memalign(sizeof(td_t), sizeof(td_t)); + if (!final_td) + fatal("Not enough DMA memory for OHCI dummy TD!\n"); memset((void *)final_td, 0, sizeof(*final_td)); /* Linked to the previous. */ cur->next_td = virt_to_phys(final_td); /* Data structures */ ed_t *head = dma_memalign(sizeof(ed_t), sizeof(ed_t)); + if (!head) + fatal("Not enough DMA memory for OHCI data structures.\n"); memset((void*)head, 0, sizeof(*head)); head->config = (dev->address << ED_FUNC_SHIFT) | (0 << ED_EP_SHIFT) | @@ -519,6 +533,8 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *src, int finalize) /* First TD. */ td_t *const first_td = (td_t *)dma_memalign(sizeof(td_t), sizeof(td_t)); + if (!first_td) + fatal("Not enough DMA memory for OHCI bulk transfer.\n"); memset((void *)first_td, 0, sizeof(*first_td)); cur = next = first_td; @@ -557,6 +573,8 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *src, int finalize) } /* One more TD. */ next = (td_t *)dma_memalign(sizeof(td_t), sizeof(td_t)); + if (!next) + fatal("Not enough DMA mem for TD bulk transfer.\n"); memset((void *)next, 0, sizeof(*next)); /* Linked to the previous. */ cur->next_td = virt_to_phys(next); @@ -569,6 +587,8 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *src, int finalize) /* Data structures */ ed_t *head = dma_memalign(sizeof(ed_t), sizeof(ed_t)); + if (!head) + fatal("Not enough DMA memory for OHCI bulk transfer's head.\n"); memset((void*)head, 0, sizeof(*head)); head->config = (ep->dev->address << ED_FUNC_SHIFT) | ((ep->endpoint & 0xf) << ED_EP_SHIFT) | @@ -665,6 +685,11 @@ ohci_create_intr_queue(endpoint_t *const ep, const int reqsize, intr_queue_t *const intrq = (intr_queue_t *)dma_memalign(sizeof(intrq->ed), sizeof(*intrq)); + if (!intrq) { + usb_debug("Not enough DMA memory for intr queue.\n"); + free(intrq); + return NULL; + } memset(intrq, 0, sizeof(*intrq)); intrq->data = (u8 *)dma_malloc(reqcount * reqsize); intrq->reqsize = reqsize; @@ -674,6 +699,8 @@ ohci_create_intr_queue(endpoint_t *const ep, const int reqsize, u8 *cur_data = intrq->data; for (i = 0; i < reqcount; ++i) { intrq_td_t *const td = dma_memalign(sizeof(td->td), sizeof(*td)); + if (!td) + fatal("Not enough DMA mem to transfer descriptor.\n"); ++intrq->remaining_tds; ohci_fill_intrq_td(td, intrq, cur_data); cur_data += reqsize; @@ -686,6 +713,8 @@ ohci_create_intr_queue(endpoint_t *const ep, const int reqsize, /* Create last, dummy TD. */ intrq_td_t *dummy_td = dma_memalign(sizeof(dummy_td->td), sizeof(*dummy_td)); + if (!dummy_td) + fatal("Not enough memory to add dummy TD.\n"); memset(dummy_td, 0, sizeof(*dummy_td)); dummy_td->intrq = intrq; if (last_td) |