public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1
@ 2022-08-22  0:53 Reid Wahl
  2022-08-22  2:39 ` Reid Wahl
  0 siblings, 1 reply; 6+ messages in thread
From: Reid Wahl @ 2022-08-22  0:53 UTC (permalink / raw)
  To: gcc-help

Hello,

I'm hitting a strange issue with GCC while trying to wrap and mock
snprintf() for unit testing purposes.

I'm setting -fno-builtin and -fno-inline, but
__builtin___snprintf_chk() is getting called instead of snprintf().
The net effect is that my __wrap__snprintf() never gets called. Do you
have any advice on how to prevent object size checking builtins from
being used, without setting a lower optimization level? I expected
-fno-builtin to take care of it.

Note that out of my whole multi-distro test bed, I've only observed
this issue on Ubuntu 22.04, Ubuntu 20.04, and Fedora 36 Power 9. I
don't have direct access to the test machines, but I spun up an Ubuntu
22.04 reproducer. It uses gcc version 11.2.0-19ubuntu1.

A known working Fedora 36 x86_64 system uses gcc version 12.1.1
20220507. On that system, snprintf() (or more accurately
__wrap_snprintf()) gets called as expected, instead of the builtin.
There are also RHEL 7 machines in the testbed, so it works fine on
older versions as well.

Minimal reproducer:
```
# cat test.c
#include <stdio.h>
void func(const char *s)
{
    char buf[16];
    snprintf(buf, 16, "%s", s);
    printf("%s\n", buf);
}
int main(void)
{
    func("hello world");
}

# gcc -g -O2 -fno-builtin -fno-inline test.c -o test
# gdb -q ./test
Reading symbols from ./test...
(gdb) b 5
Breakpoint 1 at 0x10a0: file test.c, line 9.
(gdb) r
Starting program: /root/git/pacemaker/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at test.c:9
9    {
(gdb) s
10        func("hello world");
(gdb)
func (s=s@entry=0x55555555600b "hello world") at test.c:3
3    {
(gdb)
5        snprintf(buf, 16, "%s", s);
(gdb)
0x00005555555551b9 in snprintf (__fmt=<optimized out>, __n=<optimized
out>, __s=<optimized out>) at
/usr/include/x86_64-linux-gnu/bits/stdio2.h:71
71      return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
```

Thank you.

-- 
Regards,

Reid Wahl (He/Him)
Senior Software Engineer, Red Hat
RHEL High Availability - Pacemaker


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

* Re: -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1
  2022-08-22  0:53 -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1 Reid Wahl
@ 2022-08-22  2:39 ` Reid Wahl
  2022-08-22  3:03   ` Xi Ruoyao
  2022-08-22  8:41   ` Florian Weimer
  0 siblings, 2 replies; 6+ messages in thread
From: Reid Wahl @ 2022-08-22  2:39 UTC (permalink / raw)
  To: gcc-help

On Sun, Aug 21, 2022 at 5:53 PM Reid Wahl <nwahl@redhat.com> wrote:
>
> Hello,
>
> I'm hitting a strange issue with GCC while trying to wrap and mock
> snprintf() for unit testing purposes.
>
> I'm setting -fno-builtin and -fno-inline, but
> __builtin___snprintf_chk() is getting called instead of snprintf().
> The net effect is that my __wrap__snprintf() never gets called. Do you
> have any advice on how to prevent object size checking builtins from
> being used, without setting a lower optimization level? I expected
> -fno-builtin to take care of it.
>
> Note that out of my whole multi-distro test bed, I've only observed
> this issue on Ubuntu 22.04, Ubuntu 20.04, and Fedora 36 Power 9. I
> don't have direct access to the test machines, but I spun up an Ubuntu
> 22.04 reproducer. It uses gcc version 11.2.0-19ubuntu1.
>
> A known working Fedora 36 x86_64 system uses gcc version 12.1.1
> 20220507. On that system, snprintf() (or more accurately
> __wrap_snprintf()) gets called as expected, instead of the builtin.
> There are also RHEL 7 machines in the testbed, so it works fine on
> older versions as well.
>
> Minimal reproducer:
> ```
> # cat test.c
> #include <stdio.h>
> void func(const char *s)
> {
>     char buf[16];
>     snprintf(buf, 16, "%s", s);
>     printf("%s\n", buf);
> }
> int main(void)
> {
>     func("hello world");
> }
>
> # gcc -g -O2 -fno-builtin -fno-inline test.c -o test
> # gdb -q ./test
> Reading symbols from ./test...
> (gdb) b 5
> Breakpoint 1 at 0x10a0: file test.c, line 9.
> (gdb) r
> Starting program: /root/git/pacemaker/test
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
>
> Breakpoint 1, main () at test.c:9
> 9    {
> (gdb) s
> 10        func("hello world");
> (gdb)
> func (s=s@entry=0x55555555600b "hello world") at test.c:3
> 3    {
> (gdb)
> 5        snprintf(buf, 16, "%s", s);
> (gdb)
> 0x00005555555551b9 in snprintf (__fmt=<optimized out>, __n=<optimized
> out>, __s=<optimized out>) at
> /usr/include/x86_64-linux-gnu/bits/stdio2.h:71
> 71      return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
> ```
>
> Thank you.
>
> --
> Regards,
>
> Reid Wahl (He/Him)
> Senior Software Engineer, Red Hat
> RHEL High Availability - Pacemaker

I figured out the Ubuntu issue. `man gcc` under `-O2`:

           NOTE: In Ubuntu 8.10 and later versions,
-D_FORTIFY_SOURCE=2 is set by default, and is activated when -O is set
to 2 or higher.  This enables additional compile-time and run-time
checks for
           several libc functions.  To disable, specify either
-U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0.

I have no idea what's causing the unit test to fail on Fedora 36 Power
9 LE (the only system in the test bed that's still failing), but I
don't have a reproducer or enough information to ask a question. I'll
try to get one set up this week and go from there.

-- 
Regards,

Reid Wahl (He/Him)
Senior Software Engineer, Red Hat
RHEL High Availability - Pacemaker


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

* Re: -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1
  2022-08-22  2:39 ` Reid Wahl
@ 2022-08-22  3:03   ` Xi Ruoyao
  2022-08-22  4:07     ` Reid Wahl
  2022-08-22  8:41   ` Florian Weimer
  1 sibling, 1 reply; 6+ messages in thread
From: Xi Ruoyao @ 2022-08-22  3:03 UTC (permalink / raw)
  To: Reid Wahl, gcc-help

On Sun, 2022-08-21 at 19:39 -0700, Reid Wahl via Gcc-help wrote:

For the title: -fno-builtin only prevents gcc to convert foo() to
__builtin_foo().  If you write __builtin_foo() directly built-in will be
used with or without -fno-builtin.

The remaining discussion is not related to GCC anyway. _FORTIFY_SOURCE
is a Glibc (not GCC) feature, and it's just enabled by default because
the distro is *too* smart...  I completely agree to add -
D_FORTIFY_SOURCE when they build their .deb packages, but hard wiring
this into GCC is just puzzling new users and causing them to wrongly
believe this was a "feature" of vanilla GCC.  To make things worse, many
people use Ubuntu as their first Linux distro...

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

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

* Re: -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1
  2022-08-22  3:03   ` Xi Ruoyao
@ 2022-08-22  4:07     ` Reid Wahl
  0 siblings, 0 replies; 6+ messages in thread
From: Reid Wahl @ 2022-08-22  4:07 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: gcc-help

On Sunday, August 21, 2022, Xi Ruoyao <xry111@xry111.site> wrote:
> On Sun, 2022-08-21 at 19:39 -0700, Reid Wahl via Gcc-help wrote:
>
> For the title: -fno-builtin only prevents gcc to convert foo() to
> __builtin_foo().  If you write __builtin_foo() directly built-in will be
> used with or without -fno-builtin.

Right. I was trying to keep the title short, but the issue was that
snprintf() was being essentially replaced by __builtin___snprintf_chk()
when I thought -fno-builtin should prevent any automatic replacements by
__builtin_ function calls.

>
> The remaining discussion is not related to GCC anyway. _FORTIFY_SOURCE
> is a Glibc (not GCC) feature, and it's just enabled by default because
> the distro is *too* smart...  I completely agree to add -
> D_FORTIFY_SOURCE when they build their .deb packages, but hard wiring
> this into GCC is just puzzling new users and causing them to wrongly
> believe this was a "feature" of vanilla GCC.  To make things worse, many
> people use Ubuntu as their first Linux distro...

I wasn't aware of _FORTIFY_SOURCE when I sent my first email. I read about
__builtin___snprintf_chk() in the GCC documentation:
https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html

And I agree with you. Especially since no other distro is doing that AFAIK,
it's just confusing until you figure out what's going on. Even Debian
doesn't do it. We have Debian systems in the same testbed and there are no
errors there.


>
> --
> Xi Ruoyao <xry111@xry111.site>
> School of Aerospace Science and Technology, Xidian University
>
>

-- 
Regards,

Reid Wahl (He/Him)
Senior Software Engineer, Red Hat
RHEL High Availability - Pacemaker

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

* Re: -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1
  2022-08-22  2:39 ` Reid Wahl
  2022-08-22  3:03   ` Xi Ruoyao
@ 2022-08-22  8:41   ` Florian Weimer
  2022-08-22  8:54     ` Reid Wahl
  1 sibling, 1 reply; 6+ messages in thread
From: Florian Weimer @ 2022-08-22  8:41 UTC (permalink / raw)
  To: Reid Wahl via Gcc-help

* Reid Wahl via Gcc-help:

> I have no idea what's causing the unit test to fail on Fedora 36 Power
> 9 LE (the only system in the test bed that's still failing), but I
> don't have a reproducer or enough information to ask a question. I'll
> try to get one set up this week and go from there.

The POWER failure could be related to the float128 redirects.  The
snprintf symbol is necessarily different there as well
(__snprintfieee128).  This is completely unrelated to fortification.

I must say I do not find it particularly helpful to label this as
off-topic on the gcc-help list.  Source foritification is a feature that
sits between GCC and glibc.  GCC is very much aware of what the chk
variants do.

Thanks,
Florian


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

* Re: -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1
  2022-08-22  8:41   ` Florian Weimer
@ 2022-08-22  8:54     ` Reid Wahl
  0 siblings, 0 replies; 6+ messages in thread
From: Reid Wahl @ 2022-08-22  8:54 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Reid Wahl via Gcc-help

On Monday, August 22, 2022, Florian Weimer <fweimer@redhat.com> wrote:
> * Reid Wahl via Gcc-help:
>
>> I have no idea what's causing the unit test to fail on Fedora 36 Power
>> 9 LE (the only system in the test bed that's still failing), but I
>> don't have a reproducer or enough information to ask a question. I'll
>> try to get one set up this week and go from there.
>
> The POWER failure could be related to the float128 redirects.  The
> snprintf symbol is necessarily different there as well
> (__snprintfieee128).  This is completely unrelated to fortification.

It is, thank you :) I later got a test system and discovered this --
planned to send a follow-up email and you beat me to it.

>
> I must say I do not find it particularly helpful to label this as
> off-topic on the gcc-help list.  Source foritification is a feature that
> sits between GCC and glibc.  GCC is very much aware of what the chk
> variants do.
>
> Thanks,
> Florian
>
>

-- 
Regards,

Reid Wahl (He/Him)
Senior Software Engineer, Red Hat
RHEL High Availability - Pacemaker

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

end of thread, other threads:[~2022-08-22  8:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-22  0:53 -fno-builtin not preventing __builtin___snprintf_chk in gcc 11.2.0-19ubuntu1 Reid Wahl
2022-08-22  2:39 ` Reid Wahl
2022-08-22  3:03   ` Xi Ruoyao
2022-08-22  4:07     ` Reid Wahl
2022-08-22  8:41   ` Florian Weimer
2022-08-22  8:54     ` Reid Wahl

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).