[PATCH 3/3] UBUNTU: SAUCE: opennsl: bde: check for out-of-bounds index io.dev
Kleber Souza
kleber.souza at canonical.com
Mon Oct 30 16:04:52 UTC 2017
On 09/20/17 12:27, Colin King wrote:
> 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);
Colin,
Was the check under LUBDE_GET_NUM_DEVICES deliberately left out?
> 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:
>
More information about the kernel-team
mailing list