Bug 92942 - missing -Wstringop-overflow for allocations with a negative lower bound size
Summary: missing -Wstringop-overflow for allocations with a negative lower bound size
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 11.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic, patch
Depends on:
Blocks: Wstringop-overflow
  Show dependency treegraph
 
Reported: 2019-12-14 23:18 UTC by Martin Sebor
Modified: 2020-10-27 14:37 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-08-27 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2019-12-14 23:18:27 UTC
In LP64, only the buffer overflow in f() below is diagnosed.  The one in g() is not because n is determined to be in the anti-range ~[4, 18446744071562067967], i.e., the size of the object is considered to be between [0, 4] and [INT_MAX, SIZE_MAX].  (In ILP32 both calls are diagnosed).

The warning should try to determine the type of the argument to malloc() and if it's signed, assume it's not negative.

$ cat a.c && gcc -D_FORTIFY_SOURCE=2 -O2 -S -Wall a.c
#include <stdlib.h>
#include <string.h>

void* f (unsigned n)
{ 
  if (3 < n)
    n = 3;

  void *p = malloc (n);
  strcpy (p, "12345");   // buffer overflow detected
  return p;
}

void* g (int n)
{
  if (3 < n)
    n = 3;

  void *p = malloc (n);
  strcpy (p, "12345");   // buffer overflow not detected
  return p;
}
In file included from /usr/include/string.h:494,
                 from a.c:2:
In function ‘strcpy’,
    inlined from ‘f’ at a.c:10:3:
/usr/include/bits/string_fortified.h:90:10: warning: ‘__builtin_memcpy’ writing 6 bytes into a region of size between 0 and 3 [-Wstringop-overflow=]
   90 |   return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.c: In function ‘f’:
a.c:9:13: note: at offset 0 to an object with size at most 3 allocated by ‘malloc’ here
    9 |   void *p = malloc (n);
      |             ^~~~~~~~~~
Comment 1 Martin Sebor 2020-08-27 18:52:19 UTC
Testing a fix.
Comment 3 GCC Commits 2020-10-27 14:34:40 UTC
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>:

https://gcc.gnu.org/g:c0b09c1296d5334d1d264ba4d39ca932f9572330

commit r11-4441-gc0b09c1296d5334d1d264ba4d39ca932f9572330
Author: Martin Sebor <msebor@redhat.com>
Date:   Tue Oct 27 08:31:53 2020 -0600

    Add tests for PR92942 - missing -Wstringop-overflow for allocations with a negative lower bound size.
    
    gcc/testsuite/ChangeLog:
    
            PR middle-end/92942
            * gcc.dg/Wstringop-overflow-56.c: New test.
            * gcc.dg/Wstringop-overflow-57.c: Same.
Comment 4 Martin Sebor 2020-10-27 14:37:35 UTC
The patch referenced in comment #2 was never reviewed but the bug was resolved by the improvements to compute_objsize() committed as part of the fix for pr97342.  GCC 11 detects both buffer overflows:

$ gcc -O2 -S -Wall pr92942.c
pr92942.c: In function ‘f’:
pr92942.c:10:3: warning: ‘__builtin_memcpy’ writing 6 bytes into a region of size between 0 and 3 [-Wstringop-overflow=]
   10 |   strcpy (p, "12345");   // buffer overflow detected
      |   ^~~~~~~~~~~~~~~~~~~
pr92942.c:9:13: note: at offset 0 to an object with size at most 3 allocated by ‘malloc’ here
    9 |   void *p = malloc (n);
      |             ^~~~~~~~~~
pr92942.c: In function ‘g’:
pr92942.c:20:3: warning: ‘__builtin_memcpy’ writing 6 bytes into a region of size between 0 and 3 [-Wstringop-overflow=]
   20 |   strcpy (p, "12345");   // buffer overflow not detected
      |   ^~~~~~~~~~~~~~~~~~~
pr92942.c:19:13: note: at offset 0 to an object with size at most 3 allocated by ‘malloc’ here
   19 |   void *p = malloc (n);
      |             ^~~~~~~~~~