public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/94158] New: Expanded strlen causes out-of-bounds read on AMD64 target
@ 2020-03-12 21:44 parker@cyber-itl.org
  2020-03-12 21:48 ` [Bug target/94158] " pinskia at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: parker@cyber-itl.org @ 2020-03-12 21:44 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 94158
           Summary: Expanded strlen causes out-of-bounds read on AMD64
                    target
           Product: gcc
           Version: 9.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: parker@cyber-itl.org
  Target Milestone: ---

On AMD64/Linux, When strlen() is expanded, if the argument to strlen comes from
a source like strdup() or other functions returning allocator generated
pointers, the expanded strlen() makes an assumption about the alignment of the
char array.

Expanded strlen():

  callq  0x4011e0 <strdup>

  mov    %rax,%rsi
  mov    %rax,%rdx

  mov    (%rdx),%ecx
  add    $0x4,%rdx
  lea    -0x1010101(%rcx),%eax
  not    %ecx
  and    %ecx,%eax
  and    $0x80808080,%eax
  je     0x40109a <main+58>

If the input argument is not 4-byte aligned, the "mov (%rdx),%ecx" can read up
to 3 bytes off the end of the allocated array.

Testing with GCC 9.2.1 this expanding behavior can be trigger with -O2 and -O3.
 On git HEAD (c56871dd15a258c8775740194e6ed960a1f3d850) it requires the
'-minline-all-stringops' flag and -O2 / -O3.

Reproduction:



#include <stdio.h>
#include <sys/mman.h>

#define PAGE_SIZE       4096
#define ALIGN_SIZE(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))

char *strdup(const char *str) {
    size_t size = __builtin_strlen(str) + 1;
    size_t len = ALIGN_SIZE(size);
    char *ptr = (char *) mmap(NULL, len + PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    munmap(&ptr[len], PAGE_SIZE);
    char *dest = ptr + PAGE_SIZE - size;
    __builtin_memcpy(dest, str, size);
    return dest;
}

int main(int argc, char **argv) {
    char blah[] = "AAAABBBBCCCCDD";
    char *dest = strdup(blah);
    __builtin_printf("%s %ld\n", dest, __builtin_strlen(dest));

    return 0;
}




Newer than 9.2.1:
gcc -minline-all-stringops -O2 -o strlen-crash ./strlen-crash.c

9.2.1 and below:
gcc -O2 -o strlen-crash ./strlen-crash.c


./strlen-crash # Should SIGSEGV on the 'mov (%rdx),%ecx' instruction, if
expanded.


GCC -v output:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib
--libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info
--with-pkgversion='Arch Linux 9.2.1+20200130-2'
--with-bugurl=https://bugs.archlinux.org/
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-shared
--enable-threads=posix --with-system-zlib --with-isl --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch
--disable-libssp --enable-gnu-unique-object --enable-linker-build-id
--enable-lto --enable-plugin --enable-install-libiberty
--with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib
--disable-werror --enable-checking=release --enable-default-pie
--enable-default-ssp --enable-cet=auto gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
gcc version 9.2.1 20200130 (Arch Linux 9.2.1+20200130-2)


GCC -v from git HEAD (c56871dd15a258c8775740194e6ed960a1f3d850):
Using built-in specs.
COLLECT_GCC=./bin/gcc
COLLECT_LTO_WRAPPER=/tmp/gcc/build-bins/libexec/gcc/x86_64-pc-linux-gnu/10.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --prefix=/tmp/gcc/build-bins/
--enable-languages=c,c++ --disable-bootstrap --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.0.1 20200312 (experimental) (GCC)

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

end of thread, other threads:[~2020-03-12 22:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-12 21:44 [Bug target/94158] New: Expanded strlen causes out-of-bounds read on AMD64 target parker@cyber-itl.org
2020-03-12 21:48 ` [Bug target/94158] " pinskia at gcc dot gnu.org
2020-03-12 21:52 ` pinskia at gcc dot gnu.org
2020-03-12 21:59 ` parker@cyber-itl.org
2020-03-12 22:25 ` pinskia at gcc dot gnu.org
2020-03-12 22:26 ` pinskia at gcc dot gnu.org
2020-03-12 22:31 ` jakub at gcc dot gnu.org
2020-03-12 22:38 ` parker@cyber-itl.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).