public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/89161] Bogus -Wformat-overflow warning with value range known
       [not found] <bug-89161-4@http.gcc.gnu.org/bugzilla/>
@ 2020-05-01 17:50 ` msebor at gcc dot gnu.org
  2020-10-13  4:26 ` sisyphus359 at gmail dot com
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 4+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-05-01 17:50 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|9.0                         |10.0, 9.2.0
   Last reconfirmed|2019-02-02 00:00:00         |2020-5-1

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
Reconfirming with GCC 10 with slightly different output:

pr89161.c:7: sprintf: objsize = 3, fmtstr = ".%1u"
  Directive 1 at offset 0: ".", length = 1
    Result: 1, 1, 1, 1 (1, 1, 1, 1)
  Directive 2 at offset 1: "%1u"
pr89161.c: In function ‘main’:
pr89161.c:7:24: warning: ‘%1u’ directive writing between 1 and 6 bytes into a
region of size 2 [-Wformat-overflow=]
    7 |         sprintf(buf, ".%1u", (10 * a[0]) / a[1]);
      |                        ^~~
pr89161.c:7:22: note: directive argument in the range [0, 327675]
    7 |         sprintf(buf, ".%1u", (10 * a[0]) / a[1]);
      |                      ^~~~~~
    Result: 1, 6, 6, 6 (2, 7, 7, 7)
  Directive 3 at offset 4: "", length = 1
pr89161.c:7:9: note: ‘sprintf’ output between 3 and 8 bytes into a destination
of size 3
    7 |         sprintf(buf, ".%1u", (10 * a[0]) / a[1]);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/89161] Bogus -Wformat-overflow warning with value range known
       [not found] <bug-89161-4@http.gcc.gnu.org/bugzilla/>
  2020-05-01 17:50 ` [Bug c/89161] Bogus -Wformat-overflow warning with value range known msebor at gcc dot gnu.org
@ 2020-10-13  4:26 ` sisyphus359 at gmail dot com
  2020-10-14 17:53 ` msebor at gcc dot gnu.org
  2022-01-19 17:35 ` msebor at gcc dot gnu.org
  3 siblings, 0 replies; 4+ messages in thread
From: sisyphus359 at gmail dot com @ 2020-10-13  4:26 UTC (permalink / raw)
  To: gcc-bugs

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

sisyphus359 at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sisyphus359 at gmail dot com

--- Comment #3 from sisyphus359 at gmail dot com ---
Another demo of just how nasty this bug can be.
(Apologies if this adds nothing to what has already been ascertained.)

/********************************/
/* overflow.c                           *
 * Build with (eg):                     *
 * gcc -o overflow overflow.c -O2 -Wall */
#include <stdio.h>

void foo(double, unsigned int);

int main(void) {
 double d = 5.1;
 unsigned int precis = 15;

 foo(d, precis);                 
}

void foo(double dub, unsigned int prec) {
 char buf[127];
 if(
   prec < sizeof(buf) && /** LINE 18 **/
   sizeof(buf) - prec > 10
   ){
   sprintf (buf, "%.*g", prec, dub); /** LINE 21 **/
   printf("%s\n", buf);
 }
}

/********************************/

The warning is:

overflow.c:21:19: warning: '%.*g' directive writing between 1 and 133 bytes
into a region of size 127 [-Wformat-overflow=]
    sprintf (buf, "%.*g", prec, dub);
                   ^~~~
overflow.c:21:18: note: assuming directive output of 132 bytes
    sprintf (buf, "%.*g", prec, dub);
                  ^~~~~~
overflow.c:21:4: note: 'sprintf' output between 2 and 134 bytes into a
destination of size 127
    sprintf (buf, "%.*g", prec, dub);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

and I'm seeing it on Ubuntu-20.04, gcc-9.3.0 and on Windows 7, gcc-8.3.0.

That's the message as seen on Windows, and it's essentially the same as appears
on Ubuntu except that Ubuntu appends some additional noise:

In file included from /usr/include/stdio.h:867,
                 from overflow.c:4:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note:
‘__builtin___sprintf_chk’ output between 2 and 134 bytes into a destination of
size 127
   36 |   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   37 |       __bos (__s), __fmt, __va_arg_pack ());
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


A couple of things to note:
1) AFAICS, a buffer overflow cannot occur unless sizeof(buf) - prec wraps to a
value greater than 10. That's why we check in advance that prec < sizeof(ebuf)
at line 18.

2) If I comment out the first condition (ie line 18) then no warning is issued,
even though the removal of that condition opens the door to buffer overflow
occurring.

Cheers,
Rob

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/89161] Bogus -Wformat-overflow warning with value range known
       [not found] <bug-89161-4@http.gcc.gnu.org/bugzilla/>
  2020-05-01 17:50 ` [Bug c/89161] Bogus -Wformat-overflow warning with value range known msebor at gcc dot gnu.org
  2020-10-13  4:26 ` sisyphus359 at gmail dot com
@ 2020-10-14 17:53 ` msebor at gcc dot gnu.org
  2022-01-19 17:35 ` msebor at gcc dot gnu.org
  3 siblings, 0 replies; 4+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-10-14 17:53 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
This should be resolved once the sprintf + strlen pass is converted to the new
Ranger implementation sometime in the coming weeks (hopefully).

In the meantime, changing the controlling expression in the if statement in the
test case in comment #3 to (prec < sizeof buf - 10) should also help.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/89161] Bogus -Wformat-overflow warning with value range known
       [not found] <bug-89161-4@http.gcc.gnu.org/bugzilla/>
                   ` (2 preceding siblings ...)
  2020-10-14 17:53 ` msebor at gcc dot gnu.org
@ 2022-01-19 17:35 ` msebor at gcc dot gnu.org
  3 siblings, 0 replies; 4+ messages in thread
From: msebor at gcc dot gnu.org @ 2022-01-19 17:35 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|10.0                        |10.3.0, 11.2.0, 12.0
   Last reconfirmed|2020-05-01 00:00:00         |2022-1-19

--- Comment #5 from Martin Sebor <msebor at gcc dot gnu.org> ---
GCC 12 or 11 don't warn on the test case in comment #3 but reconfirming the
warning for the test case in comment #0 with GCC 12:

$ gcc -O2 -S -Wall  -fdump-tree-strlen=/dev/stdout pr89161.c 

;; Function main (main, funcdef_no=12, decl_uid=2421, cgraph_uid=13,
symbol_order=13) (executed once)

...
pr89161.c:7: sprintf: objsize = 3, fmtstr = ".%1u"
  Directive 1 at offset 0: ".", length = 1
    Result: 1, 1, 1, 1 (1, 1, 1, 1)
  Directive 2 at offset 1: "%1u"
pr89161.c: In function ‘main’:
pr89161.c:7:24: warning: ‘%1u’ directive writing between 1 and 6 bytes into a
region of size 2 [-Wformat-overflow=]
    7 |         sprintf(buf, ".%1u", (10 * a[0]) / a[1]);
      |                        ^~~
In function ‘print’,
    inlined from ‘main’ at pr89161.c:17:5:
pr89161.c:7:22: note: directive argument in the range [0, 327670]
    7 |         sprintf(buf, ".%1u", (10 * a[0]) / a[1]);
      |                      ^~~~~~
    Result: 1, 6, 6, 6 (2, 7, 7, 7)
  Directive 3 at offset 4: "", length = 1
pr89161.c:7:9: note: ‘sprintf’ output between 3 and 8 bytes into a destination
of size 3
    7 |         sprintf(buf, ".%1u", (10 * a[0]) / a[1]);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-01-19 17:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <bug-89161-4@http.gcc.gnu.org/bugzilla/>
2020-05-01 17:50 ` [Bug c/89161] Bogus -Wformat-overflow warning with value range known msebor at gcc dot gnu.org
2020-10-13  4:26 ` sisyphus359 at gmail dot com
2020-10-14 17:53 ` msebor at gcc dot gnu.org
2022-01-19 17:35 ` msebor at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).