public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/105654] New: Address of local variable as function call argument is NULL?!
@ 2022-05-19  6:41 gnu.org at quisquis dot de
  2022-05-19 11:13 ` [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed rguenth at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: gnu.org at quisquis dot de @ 2022-05-19  6:41 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 105654
           Summary: Address of local variable as function call argument is
                    NULL?!
           Product: gcc
           Version: 12.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gnu.org at quisquis dot de
  Target Milestone: ---

Created attachment 52993
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52993&action=edit
Preprocessed example code

Problem
=======
The address of a local variable is used as the argument in a function call. The
actual value passed to the call is 0, which subsequently leads to a segfault.

Context
=======
The strongswan project uses a somewhat obscure construct in some of its option
processing code, which is where the problem was initially detected. See
https://github.com/strongswan/strongswan/issues/1053#issuecomment-1130134332 .

The behaviour was first observed with gcc-12.1. gcc-11.2.1 is apparently not
affected. The problem disappears with either
* -O0 optimiziation
* -fsanitize=undefined
* the "parse" function pointer not declared static

Compiler invocation
===================

> env -u LANG gcc -v  --save-temps -o test -g -O1 -Wall -Wextra  test.c 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
--enable-languages=c,c++,objc,fortran,obj-c++,ada,go,d,jit
--enable-offload-targets=nvptx-none,amdgcn-amdhsa, --enable-offload-defaulted
--without-cuda-driver --enable-host-shared --enable-checking=release
--disable-werror --with-gxx-include-dir=/usr/include/c++/12 --enable-ssp
--disable-libssp --disable-libvtv --enable-cet=auto --disable-libcc1
--enable-plugin --with-bugurl=https://bugs.opensuse.org/
--with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib
--enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-libphobos
--enable-version-specific-runtime-libs --with-gcc-major-version-only
--enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function
--program-suffix=-12 --without-system-libunwind --enable-multilib
--with-arch-32=x86-64 --with-tune=generic
--with-build-config=bootstrap-lto-lean --enable-link-mutex
--build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.1.1 20220517 [revision 325d82b08696da17fb26bd2e1b6ba607649357fb]
(SUSE Linux) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-g' '-O1' '-Wall' '-Wextra'
'-mtune=generic' '-march=x86-64'
 /usr/lib64/gcc/x86_64-suse-linux/12/cc1 -E -quiet -v test.c -mtune=generic
-march=x86-64 -Wall -Wextra -g -fworking-directory -O1 -fpch-preprocess -o
test.i
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib64/gcc/x86_64-suse-linux/12/include
 /usr/local/include
 /usr/lib64/gcc/x86_64-suse-linux/12/include-fixed
 /usr/lib64/gcc/x86_64-suse-linux/12/../../../../x86_64-suse-linux/include
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-g' '-O1' '-Wall' '-Wextra'
'-mtune=generic' '-march=x86-64'
 /usr/lib64/gcc/x86_64-suse-linux/12/cc1 -fpreprocessed test.i -quiet -dumpbase
test.c -dumpbase-ext .c -mtune=generic -march=x86-64 -g -O1 -Wall -Wextra
-version -o test.s
GNU C17 (SUSE Linux) version 12.1.1 20220517 [revision
325d82b08696da17fb26bd2e1b6ba607649357fb] (x86_64-suse-linux)
        compiled by GNU C version 12.1.1 20220517 [revision
325d82b08696da17fb26bd2e1b6ba607649357fb], GMP version 6.2.1, MPFR version
4.1.0-p7, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C17 (SUSE Linux) version 12.1.1 20220517 [revision
325d82b08696da17fb26bd2e1b6ba607649357fb] (x86_64-suse-linux)
        compiled by GNU C version 12.1.1 20220517 [revision
325d82b08696da17fb26bd2e1b6ba607649357fb], GMP version 6.2.1, MPFR version
4.1.0-p7, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 00000000000000000000000000000000
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-g' '-O1' '-Wall' '-Wextra'
'-mtune=generic' '-march=x86-64'
 /usr/lib64/gcc/x86_64-suse-linux/12/../../../../x86_64-suse-linux/bin/as -v
--gdwarf-5 --64 -o test.o test.s
GNU assembler version 2.38 (x86_64-suse-linux) using BFD version (GNU Binutils;
openSUSE Tumbleweed) 2.38.20220411-5
COMPILER_PATH=/usr/lib64/gcc/x86_64-suse-linux/12/:/usr/lib64/gcc/x86_64-suse-linux/12/:/usr/lib64/gcc/x86_64-suse-linux/:/usr/lib64/gcc/x86_64-suse-linux/12/:/usr/lib64/gcc/x86_64-suse-linux/:/usr/lib64/gcc/x86_64-suse-linux/12/../../../../x86_64-suse-linux/bin/
LIBRARY_PATH=/usr/lib64/gcc/x86_64-suse-linux/12/:/usr/lib64/gcc/x86_64-suse-linux/12/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib64/gcc/x86_64-suse-linux/12/../../../../x86_64-suse-linux/lib/:/usr/lib64/gcc/x86_64-suse-linux/12/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-g' '-O1' '-Wall' '-Wextra'
'-mtune=generic' '-march=x86-64' '-dumpdir' 'test.'
 /usr/lib64/gcc/x86_64-suse-linux/12/collect2 -plugin
/usr/lib64/gcc/x86_64-suse-linux/12/liblto_plugin.so
-plugin-opt=/usr/lib64/gcc/x86_64-suse-linux/12/lto-wrapper
-plugin-opt=-fresolution=test.res -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id
--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o
test /usr/lib64/gcc/x86_64-suse-linux/12/../../../../lib64/crt1.o
/usr/lib64/gcc/x86_64-suse-linux/12/../../../../lib64/crti.o
/usr/lib64/gcc/x86_64-suse-linux/12/crtbegin.o
-L/usr/lib64/gcc/x86_64-suse-linux/12
-L/usr/lib64/gcc/x86_64-suse-linux/12/../../../../lib64 -L/lib/../lib64
-L/usr/lib/../lib64
-L/usr/lib64/gcc/x86_64-suse-linux/12/../../../../x86_64-suse-linux/lib
-L/usr/lib64/gcc/x86_64-suse-linux/12/../../.. test.o -lgcc --push-state
--as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s
--pop-state /usr/lib64/gcc/x86_64-suse-linux/12/crtend.o
/usr/lib64/gcc/x86_64-suse-linux/12/../../../../lib64/crtn.o
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-g' '-O1' '-Wall' '-Wextra'
'-mtune=generic' '-march=x86-64' '-dumpdir' 'test.'

Crash
=====
> gdb --args test yes
GNU gdb (GDB; openSUSE Tumbleweed) 11.1
[...]
Reading symbols from test...
(gdb) r
Starting program: /tmp/tmp/test yes
Missing separate debuginfos, use: zypper install
glibc-debuginfo-2.35-2.4.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401166 in _cb_parse (out=out@entry=0x0, in=<optimized out>) at
test.c:9
9           *out = !strcmp("yes", in);
(gdb) 

(notice "out=out@entry=0x0")

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

* [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed
  2022-05-19  6:41 [Bug c/105654] New: Address of local variable as function call argument is NULL?! gnu.org at quisquis dot de
@ 2022-05-19 11:13 ` rguenth at gcc dot gnu.org
  2022-05-19 11:34 ` schwab@linux-m68k.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-05-19 11:13 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu.org,
                   |                            |jsm28 at gcc dot gnu.org

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
-fno-ipa-modref fixes this, the issue is we remove the initialization of the
out argument:

--- t.i.113t.mergephi2  2022-05-19 13:06:52.209819846 +0200
+++ t.i.116t.dse2       2022-05-19 13:06:52.209819846 +0200
@@ -45,7 +45,6 @@

   <bb 4> [local count: 912787929]:
   _2 = MEM[(char * *)argv_10(D) + 8B];
-  D.2620.x = &val;
   _cb_parse (D.2620, _2);
   val.1_3 = val;
   _4 = (int) val.1_3;

note there's a mismatch between the prototype and the actual _cb_parse
declaration:

static _Bool _cb_parse(union { void* x; _Bool * out; }
__attribute((transparent_union)), char* in);
static typeof(_cb_parse)* parse = _cb_parse;

and

static _Bool _cb_parse( _Bool * out, char* in) {
    *out = !strcmp("yes", in);
    return;
}

with the call being indirect:

    parse(&val, argv[1]);

The docs say

'Second, the argument is passed to the function using the calling
conventions of the first member of the transparent union, not the calling
conventions of the union itself.  All members of the union must have the
same machine representation; this is necessary for this argument passing
to work properly.'

so possibly the alias set of the union needs to be that of the first member
but then the _cb_parse implementation uses _Bool * to access the argument
which then breaks.

But I suppose the issue with modref is more subtle due to the pointer
SSA name in the implementation and the aggregate argument in the caller.

Honza?

Joseph - is the above well-defined use of the extension?

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

* [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed
  2022-05-19  6:41 [Bug c/105654] New: Address of local variable as function call argument is NULL?! gnu.org at quisquis dot de
  2022-05-19 11:13 ` [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed rguenth at gcc dot gnu.org
@ 2022-05-19 11:34 ` schwab@linux-m68k.org
  2022-05-19 12:25 ` schwab@linux-m68k.org
  2022-05-20 12:59 ` tobias at strongswan dot org
  3 siblings, 0 replies; 5+ messages in thread
From: schwab@linux-m68k.org @ 2022-05-19 11:34 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andreas Schwab <schwab@linux-m68k.org> ---
FWIW, glibc has removed the use of transparent_union from its wait
implementation long ago.

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

* [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed
  2022-05-19  6:41 [Bug c/105654] New: Address of local variable as function call argument is NULL?! gnu.org at quisquis dot de
  2022-05-19 11:13 ` [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed rguenth at gcc dot gnu.org
  2022-05-19 11:34 ` schwab@linux-m68k.org
@ 2022-05-19 12:25 ` schwab@linux-m68k.org
  2022-05-20 12:59 ` tobias at strongswan dot org
  3 siblings, 0 replies; 5+ messages in thread
From: schwab@linux-m68k.org @ 2022-05-19 12:25 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andreas Schwab <schwab@linux-m68k.org> ---
The declaration with the transparent union allows redeclarations with either of
the contained types.

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

* [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed
  2022-05-19  6:41 [Bug c/105654] New: Address of local variable as function call argument is NULL?! gnu.org at quisquis dot de
                   ` (2 preceding siblings ...)
  2022-05-19 12:25 ` schwab@linux-m68k.org
@ 2022-05-20 12:59 ` tobias at strongswan dot org
  3 siblings, 0 replies; 5+ messages in thread
From: tobias at strongswan dot org @ 2022-05-20 12:59 UTC (permalink / raw)
  To: gcc-bugs

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

Tobias Brunner <tobias at strongswan dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |tobias at strongswan dot org

--- Comment #4 from Tobias Brunner <tobias at strongswan dot org> ---
Note that changing the macro so that instead of

  static typeof(_cb_parse)* parse = _cb_parse;

it declares the function like this

  static _Bool (*parse)(void*, char* in) = _cb_parse;

seems to fix the issue (see my update here:
https://github.com/strongswan/strongswan/issues/1053#issuecomment-1131356912).

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

end of thread, other threads:[~2022-05-20 12:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-19  6:41 [Bug c/105654] New: Address of local variable as function call argument is NULL?! gnu.org at quisquis dot de
2022-05-19 11:13 ` [Bug middle-end/105654] transparent_union, function pointer and different types arguments causes null pointer to be passed rguenth at gcc dot gnu.org
2022-05-19 11:34 ` schwab@linux-m68k.org
2022-05-19 12:25 ` schwab@linux-m68k.org
2022-05-20 12:59 ` tobias at strongswan dot 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).