[Bug 1612143] Re: Too-wide load generated, possibly crossing into unmapped address

Matthias Klose doko at ubuntu.com
Thu Aug 11 12:34:28 UTC 2016


please recheck with GCC 6 in yakkety

-- 
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to gcc-5 in Ubuntu.
https://bugs.launchpad.net/bugs/1612143

Title:
  Too-wide load generated, possibly crossing into unmapped address

Status in gcc-5 package in Ubuntu:
  New

Bug description:
  The following function

  void mach_parse_compressed(unsigned char* ptr, unsigned long int* val)
  {
      if (ptr[0] < 0xC0U) {
          *val = ptr[0] + ptr[1];
          return;
      }

    *val = ((unsigned long int)(ptr[0]) << 24)
        | ((unsigned long int)(ptr[1]) << 16)
        | ((unsigned long int)(ptr[2]) << 8)
        | ptr[3];
  }

  generates assembly (GCC 5.4 -O2 -fPIC on x86_64) that loads four bytes
  at ptr first, compares the first byte with 0xC0, and then processes
  either two, either four bytes. It seems that it's incorrect to load
  all four bytes before ptr[0] value has been checked. Removing -fPIC or
  reducing optimisation level makes the issue go away.

  Here's a demo program containing this function that crashes directly
  if #define MMAP, and shows ASan error in stack (nothing defined) and
  ASan/Valgrind error in heap (#define HEAP) version:

  //#define HEAP
  #define MMAP
  #ifdef MMAP
  #include <unistd.h>
  #include <sys/mman.h>
  #include <stdio.h>
  #elif HEAP
  #include <stdlib.h>
  #endif

  void
  mach_parse_compressed(unsigned char* ptr, unsigned long int* val)
  {
      if (ptr[0] < 0xC0U) {
          *val = ptr[0] + ptr[1];
          return;
      }

      *val = ((unsigned long int)(ptr[0]) << 24)
          | ((unsigned long int)(ptr[1]) << 16)
          | ((unsigned long int)(ptr[2]) << 8)
          | ptr[3];
  }

  int main(void)
  {
      unsigned long int val;
  #ifdef MMAP
      int error;
      long page_size = sysconf(_SC_PAGESIZE);
      unsigned char *buf = mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE,
                                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
      unsigned char *ptr = buf + page_size - 2;
      if (buf == MAP_FAILED)
      {
          perror("mmap");
          return 1;
      }
      error = mprotect(buf + page_size, page_size, PROT_NONE);
      if (error != 0)
      {
          perror("mprotect");
          return 2;
      }
      *ptr = 0xBF;
      *(ptr + 1) = 0x10;
      mach_parse_compressed(ptr, &val);
  #elif HEAP
      unsigned char *buf = malloc(16384);
      unsigned char *ptr = buf + 16382;
      buf[16382] = 0xBF;
      buf[16383] = 0x10;
  #else
      unsigned char buf[2];
      unsigned char *ptr = buf;
      buf[0] = 0xBF;
      buf[1] = 0x10;
  #endif
      mach_parse_compressed(ptr, &val);
  }

  $ lsb_release -rd
  Description:	Ubuntu 16.04.1 LTS
  Release:	16.04

  $ gcc -v
  Using built-in specs.
  COLLECT_GCC=gcc
  COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
  Target: x86_64-linux-gnu
  Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.2' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
  Thread model: posix
  gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2) 

  $ dpkg -l gcc-5 
  Desired=Unknown/Install/Remove/Purge/Hold
  | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
  |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
  ||/ Name                                          Version                     Architecture                Description
  +++-=============================================-===========================-===========================-===============================================================================================
  ii  gcc-5                                         5.4.0-6ubuntu1~16.04.2      amd64                       GNU C compiler

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1612143/+subscriptions



More information about the foundations-bugs mailing list