ACK [PATCH 3/3] UBUNTU: SAUCE: opennsl: bde: check for out-of-bounds index io.dev

Juerg Haefliger juerg.haefliger at canonical.com
Thu Sep 21 06:15:36 UTC 2017



On 09/20/2017 12:27 PM, 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);
>          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:
> 
Acked-by: Juerg Haefliger <juerg.haefliger at canonical.com>





More information about the kernel-team mailing list