[PATCH 3/3] UBUNTU: SAUCE: opennsl: bde: check for out-of-bounds index io.dev
Colin King
colin.king at canonical.com
Wed Sep 20 10:27:07 UTC 2017
From: Colin Ian King <colin.king at canonical.com>
BugLink: https://launchpad.net/bugs/1718388
io.dev is used as an index into the _devices array and currently
the user may pass any unsigned int value into io.dev which can create
an out-of-bounds error. Fix this by sanity checking io.dev and
returning -EINVAL for out-of-bounds values of io.dev
Detected by CoverityScan CID#1456895 ("Untrusted array index read")
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
.../systems/bde/linux/user/kernel/linux-user-bde.c | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/ubuntu/opennsl/OpenNSL/sdk-6.4.10-gpl-modules/systems/bde/linux/user/kernel/linux-user-bde.c b/ubuntu/opennsl/OpenNSL/sdk-6.4.10-gpl-modules/systems/bde/linux/user/kernel/linux-user-bde.c
index 2d7a521..44adb45 100644
--- a/ubuntu/opennsl/OpenNSL/sdk-6.4.10-gpl-modules/systems/bde/linux/user/kernel/linux-user-bde.c
+++ b/ubuntu/opennsl/OpenNSL/sdk-6.4.10-gpl-modules/systems/bde/linux/user/kernel/linux-user-bde.c
@@ -912,6 +912,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
io.d0 = user_bde->num_devices(io.dev);
break;
case LUBDE_GET_DEVICE:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
bde_dev = user_bde->get_dev(io.dev);
if (bde_dev) {
io.d0 = bde_dev->device;
@@ -926,13 +928,19 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
break;
case LUBDE_GET_DEVICE_TYPE:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
io.d0 = _devices[io.dev].dev_type;
break;
case LUBDE_GET_BUS_FEATURES:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
user_bde->pci_bus_features(io.dev, (int *) &io.d0, (int *) &io.d1,
(int *) &io.d2);
break;
case LUBDE_PCI_CONFIG_PUT32:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) {
user_bde->pci_conf_write(io.dev, io.d0, io.d1);
} else {
@@ -940,6 +948,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
break;
case LUBDE_PCI_CONFIG_GET32:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) {
io.d0 = user_bde->pci_conf_read(io.dev, io.d0);
} else {
@@ -947,6 +957,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
break;
case LUBDE_GET_DMA_INFO:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
inst_id = io.dev;
if (_bde_multi_inst){
_dma_resource_get(inst_id, &pbase, &size);
@@ -959,6 +971,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
io.d2 = USE_LINUX_BDE_MMAP;
break;
case LUBDE_ENABLE_INTERRUPTS:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) {
if (_devices[io.dev].isr && !_devices[io.dev].enabled) {
user_bde->interrupt_connect(io.dev,
@@ -978,12 +992,16 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
break;
case LUBDE_DISABLE_INTERRUPTS:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (_devices[io.dev].enabled) {
user_bde->interrupt_disconnect(io.dev);
_devices[io.dev].enabled = 0;
}
break;
case LUBDE_WAIT_FOR_INTERRUPT:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) {
res = &_bde_inst_resource[_devices[io.dev].inst];
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
@@ -1040,27 +1058,39 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
break;
case LUBDE_WRITE_IRQ_MASK:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0);
break;
case LUBDE_SPI_READ_REG:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (user_bde->spi_read(io.dev, io.d0, io.dx.buf, io.d1) == -1) {
io.rc = LUBDE_FAIL;
}
break;
case LUBDE_SPI_WRITE_REG:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (user_bde->spi_write(io.dev, io.d0, io.dx.buf, io.d1) == -1) {
io.rc = LUBDE_FAIL;
}
break;
case LUBDE_READ_REG_16BIT_BUS:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
io.d1 = user_bde->read(io.dev, io.d0);
break;
case LUBDE_WRITE_REG_16BIT_BUS:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
io.rc = user_bde->write(io.dev, io.d0, io.d1);
break;
#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT))
case LUBDE_CPU_WRITE_REG:
{
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (lkbde_cpu_write(io.dev, io.d0, (uint32*)io.dx.buf) == -1) {
io.rc = LUBDE_FAIL;
}
@@ -1068,6 +1098,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
case LUBDE_CPU_READ_REG:
{
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (lkbde_cpu_read(io.dev, io.d0, (uint32*)io.dx.buf) == -1) {
io.rc = LUBDE_FAIL;
}
@@ -1075,6 +1107,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
case LUBDE_CPU_PCI_REGISTER:
{
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (lkbde_cpu_pci_register(io.dev) == -1) {
io.rc = LUBDE_FAIL;
}
@@ -1082,6 +1116,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
#endif
case LUBDE_DEV_RESOURCE:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
bde_dev = user_bde->get_dev(io.dev);
if (bde_dev) {
if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) {
@@ -1094,12 +1130,16 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
break;
case LUBDE_IPROC_READ_REG:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
io.d1 = user_bde->iproc_read(io.dev, io.d0);
if (io.d1 == -1) {
io.rc = LUBDE_FAIL;
}
break;
case LUBDE_IPROC_WRITE_REG:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
if (user_bde->iproc_write(io.dev, io.d0, io.d1) == -1) {
io.rc = LUBDE_FAIL;
}
@@ -1108,6 +1148,8 @@ _ioctl(unsigned int cmd, unsigned long arg)
io.rc = _instance_attach(io.d0, io.d1);
break;
case LUBDE_GET_DEVICE_STATE:
+ if (io.dev >= LINUX_BDE_MAX_DEVICES)
+ return -EINVAL;
io.rc = lkbde_dev_state_get(io.dev, &io.d0);
break;
default:
--
2.7.4
More information about the kernel-team
mailing list