https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106321

            Bug ID: 106321
           Summary: False positives from -Wanalyzer-tainted-array-index
                    with switch with ranged cases
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: dmalcolm at gcc dot gnu.org
  Target Milestone: ---

Consider:  https://godbolt.org/z/o3xE7PozM

static int arr[100];

int  __attribute__((tainted_args))
test_5 (int idx)
{
  switch (idx)
    {
    default:
      return 0;
    case 5 ... 20:
      return arr[idx];

    /* Extra cases to avoid optimizing the switch away.  */
    case 22:
      return 22;
    case 23:
      return -17;
    }
}

With -fanalyzer -fanalyzer-checker=taint, this falsely complains:

<source>: In function 'test_5':
<source>:11:17: warning: use of attacker-controlled value 'idx' in array lookup
without bounds checking [CWE-129] [-Wanalyzer-tainted-array-index]
   11 |       return arr[idx];
      |              ~~~^~~~~
  'test_5': event 1
    |
    |    4 | test_5 (int idx)
    |      | ^~~~~~
    |      | |
    |      | (1) function 'test_5' marked with '__attribute__((tainted_args))'
    |
    +--> 'test_5': events 2-5
           |
           |    4 | test_5 (int idx)
           |      | ^~~~~~
           |      | |
           |      | (2) entry to 'test_5'
           |    5 | {
           |    6 |   switch (idx)
           |      |   ~~~~~~
           |      |   |
           |      |   (3) following 'case 5 ... 20:' branch...
           |......
           |   10 |     case 5 ... 20:
           |      |     ~~~~
           |      |     |
           |      |     (4) ...to here
           |   11 |       return arr[idx];
           |      |              ~~~~~~~~
           |      |                 |
           |      |                 (5) use of attacker-controlled value 'idx'
in array lookup without bounds checking
           |

despite the fact that idx has had its bounds checked by dint of being used as
the switch index, and we're now within the ranged case.

Seen on Linux kernel, e.g. in drivers/vfio/pci/vfio_pci_core.c, where
vfio_pci_core_ioctl has:

    |  744 |                 switch (info.index) {
    |      |                 ~~~~~~  ~~~~~~~~~~
    |      |                 |           |
    |      |                 |           (8) ...to here
    |      |                 (9) following ‘case 0 ... 5:’ branch...
    |......
    |  751 |                 case VFIO_PCI_BAR0_REGION_INDEX ...
VFIO_PCI_BAR5_REGION_INDEX:
    |      |                 ~~~~
    |      |                 |
    |      |                 (10) ...to here

and then a false complaint about "use of attacker-controlled value ‘info.index’
in array lookup without upper-bounds checking"

Reply via email to