Bug 92943 - missing -Wformat-overflow with an allocated buffer with non-constant size in known range
Summary: missing -Wformat-overflow with an allocated buffer with non-constant size in ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 11.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic
Depends on:
Blocks: Wformat-overflow
  Show dependency treegraph
 
Reported: 2019-12-14 23:34 UTC by Martin Sebor
Modified: 2022-01-19 17:45 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 11.1.0
Known to fail: 10.3.0
Last reconfirmed: 2021-12-23 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:34:39 UTC
With pr78245 resolved, GCC diagnoses the buffer overflow in function f() below.  The overflow in g() is also detected but only after the sprintf pass has transformed the call to memcpy, and not by the pass itself.  The overflow in h() is not detected at all, (presumably) because the detection relies on the objsize pass which is limited to constant sizes.


$ cat a.c && gcc -O2 -S -Wall a.c
void* f (void)
{
  char *p = __builtin_malloc (4);
  __builtin_sprintf (p, "%i", 12345);   // overflow detected
  return p;
}

void* g (unsigned n)
{ 
  if (4 < n)
    n = 4;
  char *p = __builtin_malloc (n);
  __builtin_sprintf (p, "%s", "12345");    // overflow detected
  return p;
}

void* h (unsigned n)
{
  if (4 < n)
    n = 4;
  char *p = __builtin_malloc (n);
  __builtin_sprintf (p, "%i", 12345);   // overflow not detected
  return p;
}
a.c: In function ‘f’:
a.c:4:26: warning: ‘%i’ directive writing 5 bytes into a region of size 4 [-Wformat-overflow=]
    4 |   __builtin_sprintf (p, "%i", 12345);   // overflow detected
      |                          ^~
a.c:4:3: note: ‘__builtin_sprintf’ output 6 bytes into a destination of size 4
    4 |   __builtin_sprintf (p, "%i", 12345);   // overflow detected
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.c: In function ‘g’:
a.c:13:3: warning: ‘__builtin_memcpy’ forming offset [4, 5] is out of the bounds [0, 4] [-Warray-bounds]
   13 |   __builtin_sprintf (p, "%s", "12345");   // overflow detected
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 1 Andrew Pinski 2021-12-23 07:40:01 UTC
This seems fixed in GCC 11+:

<source>: In function 'h':
<source>:23:26: warning: '%i' directive writing 5 bytes into a region of size 4 [-Wformat-overflow=]
   23 |   __builtin_sprintf (p, "%i", 12345);   // overflow not detected
      |                          ^~
<source>:23:3: note: '__builtin_sprintf' output 6 bytes into a destination of size 4
   23 |   __builtin_sprintf (p, "%i", 12345);   // overflow not detected
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 2 Martin Sebor 2022-01-04 21:31:45 UTC
Fixed by r11-5622 (AKA PR middle-end/97373).