public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/115014] New: GCC generates incorrect instructions for addressing the data segment through EBP register
@ 2024-05-09 15:07 mdoucha at suse dot cz
  2024-05-09 15:24 ` [Bug target/115014] " pinskia at gcc dot gnu.org
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: mdoucha at suse dot cz @ 2024-05-09 15:07 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 115014
           Summary: GCC generates incorrect instructions for addressing
                    the data segment through EBP register
           Product: gcc
           Version: 13.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mdoucha at suse dot cz
  Target Milestone: ---

Created attachment 58149
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58149&action=edit
Preprocessed reproducer source file

Target: x86 (32bit)

While writing a new KVM test for the Linux Test Project, I ran into some
mysterious virtual machine crashes due to stack segment fault exception. The
test is essentially a tiny kernel that'll bootstrap a virtual CPU into
protected mode, run a few operations to test something and return results in a
predefined block of memory to the controller process running on the host
machine.

The cause of the crashes turns out to be a combination of custom stack segment
limit and GCC generating unprefixed instructions for accessing data segment
addresses through the EBP register. For example, GCC generates this
instruction:
movzbl 0x1(%ebp),%eax

When it should generate a prefixed one instead:
movzbl %ds:0x1(%ebp),%eax

This would not be a problem on most systems because the stack and data segments
are usually identical but due to the embedded nature of the KVM test, the stack
segment has special settings and the address in EBP happens to be a pointer to
string constant stored outside the stack segment limit.

The fix should be simple:
1) If the address in EBP was calculated from stack pointer value, generate
unprefixed instructions.
2) Otherwise add data segment prefix.
This condition should be applied at least if the source file is compiled for
32bit x86 with the -ffreestanding argument.

The attached source file contains a minimal reimplementation of standard C
library functions for the embedded environment. The vsprintf() reimplementation
is where the issue manifests. The source file was compiled with the following
command line options:
gcc -I../testcases/kernel/kvm/include -DCOMPILE_PAYLOAD -ffreestanding -O2
-Wall -fno-asynchronous-unwind-tables -fno-stack-protector -mno-mmx -mno-sse
-save-temps -m32 -fno-pie -c -o lib_guest.o ../testcases/kernel/kvm/lib_guest.c

Note that this is not the full KVM test which you could run to trigger the
stack segment fault exception. The full test would require:
- CPU bootstrap file in assembly[1] (see below)
- the attached reproducer file
- main test source
- test controller source
- custom linker script
- build script to tie it all together

Instead, you can just see the assembly output and look for the movzbl
instruction mentioned above.

The GCC package used for building the KVM test comes from SUSE, but I've
already talked to the SUSE maintainer (Martin Jambor) and he asked me to open
an upstream bug.


gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-suse-linux
Configured with: ../configure CFLAGS=' -O2 -funwind-tables
-fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type -g'
CXXFLAGS=' -O2 -funwind-tables -fasynchronous-unwind-tables
-fstack-clash-protection -Werror=return-type -g' XCFLAGS=' -O2 -funwind-tables
-fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type -g'
TCFLAGS=' -O2 -funwind-tables -fasynchronous-unwind-tables
-fstack-clash-protection -Werror=return-type -g' GDCFLAGS=' -O2 -funwind-tables
-fasynchronous-unwind-tables -fstack-clash-protection -g' --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,m2
--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++/13
--with-libstdcxx-zoneinfo=/usr/share/zoneinfo --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=-13 --without-system-libunwind --enable-multilib
--with-arch-32=x86-64 --with-tune=generic
--with-build-config=bootstrap-lto-lean --enable-link-serialization
--build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.1 20240206 [revision 67ac78caf31f7cb3202177e6428a46d829b70f23]
(SUSE Linux) 


The CPU bootstrap file for reference, with stack segment setup highlighted:
[1]
https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/kvm/bootstrap_x86.S#L117

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

end of thread, other threads:[~2024-05-10 12:31 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-09 15:07 [Bug target/115014] New: GCC generates incorrect instructions for addressing the data segment through EBP register mdoucha at suse dot cz
2024-05-09 15:24 ` [Bug target/115014] " pinskia at gcc dot gnu.org
2024-05-09 15:33 ` mdoucha at suse dot cz
2024-05-09 15:42 ` pinskia at gcc dot gnu.org
2024-05-09 15:58 ` mdoucha at suse dot cz
2024-05-10  3:35 ` xry111 at gcc dot gnu.org
2024-05-10  8:44 ` mdoucha at suse dot cz
2024-05-10 11:28 ` amonakov at gcc dot gnu.org
2024-05-10 11:33 ` pinskia at gcc dot gnu.org
2024-05-10 11:38 ` mdoucha at suse dot cz
2024-05-10 11:56 ` pinskia at gcc dot gnu.org
2024-05-10 12:11 ` xry111 at gcc dot gnu.org
2024-05-10 12:25 ` mdoucha at suse dot cz
2024-05-10 12:31 ` rguenth 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).