[Bug middle-end/78973] [7.0 regression] warning: ‘memcpy’: specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Jan 8 00:00:00 GMT 2017


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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |INVALID

--- Comment #6 from Martin Sebor <msebor at gcc dot gnu.org> ---
I take back what I said in comnment #4.  I had misread the range information
reported in the VRP dump and also debugged the wrong function (before it was
inlined into the caller).  I have a patch that improves the algorithm used by
the warning and adds inlining context to make debugging easier.  With it GCC
prints the following:

In file included from drivers/media/pci/ttpci/av7110.c:63:0:
In function ‘irdebi’,
    inlined from ‘start_debi_dma’ at drivers/media/pci/ttpci/av7110.c:376:3,
    inlined from ‘gpioirq’ at drivers/media/pci/ttpci/av7110.c:659:3:
drivers/media/pci/ttpci/av7110_hw.h:406:3: warning: ‘memcpy’: specified size
between 18446744071562067968 and 18446744073709551615 exceeds maximum object
size 9223372036854775807 [-Wstringop-overflow=]
In function ‘irdebi’,
    inlined from ‘start_debi_dma’ at drivers/media/pci/ttpci/av7110.c:376:3,
    inlined from ‘gpioirq’ at drivers/media/pci/ttpci/av7110.c:668:3:
drivers/media/pci/ttpci/av7110_hw.h:406:3: warning: ‘memcpy’: specified size
between 18446744071562067968 and 18446744073709551615 exceeds maximum object
size 9223372036854775807 [-Wstringop-overflow=]

There are three calls to memcpy in gpioirq.  The two that cause the warnings
are these:

  <bb 94> [7.74%]:
  _306 = (long unsigned int) len_138;
  _307 = av7110_131->debi_virt;
  memcpy (_307, &res, _306);

and

  <bb 109> [2.75%]:
  _333 = (long unsigned int) len_138;
  _334 = av7110_131->debi_virt;
  memcpy (_334, &res, _333);

The range information for both of the variables is:

  _306: [18446744071562067968, +INF]
  _333: [18446744071562067968, +INF]

which corresponds the warning messages.

The irdebi function inlined into gpioirq looks like this:

  irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
  {
    u32 res;
    res=av7110_debiread(av7110, config, addr, count);
    if (count<=4)
      memcpy(av7110->debi_virt, (char *) &res, count);
    return res;
  }

It calls memcpy with an int argument that's less than or equal to 4 (and
possibly negative).

The irdebi call is inlined into start_debi_dma:

  void start_debi_dma(struct av7110 *av7110, int dir,
        unsigned long addr, unsigned int len)
  {
    ...
    if (len < 5)
      len = 5;
    if (dir == 1)
      iwdebi(av7110, 0x001e0000, addr, 0, (len + 3) & ~3);
    else
      irdebi(av7110, 0x001e0000, addr, 0, len);
  }

I.e., with an unsigned len greater than or equal to 5 (and possibly in excess
of INT_MAX).  

start_debi_dma is called from gpioirq like so:

  int len;
  ...
  av7110->debilen = irdebi(av7110, 0x000e0000, (0x4000 + 0x0F6), 0, 2);
  ...
  len = (av7110->debilen + 3) & ~3;
  ...
  case 0x04:
    if (!len || len > 0xff) {
      iwdebi(av7110, 0x000e0000, (0x4000 + 0x1FF4), 0, 2);
      break;
    }
    start_debi_dma(av7110, 0, (0x4000 + 0x1E00), len);

len here is bounded by [INT_MIN, 0xfc], i.e., it can be negative.

In summary, I think the warning is justified and the result of the signed to
unsigned to signed conversions and insufficient checks for out of bounds values
that don't take into consideration that the signed values can be negative.


More information about the Gcc-bugs mailing list