https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77992
Bug ID: 77992 Summary: Failures to initialize padding bytes -- causing many information leaks Product: gcc Version: 5.4.0 Status: UNCONFIRMED Severity: critical Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: kjlu at gatech dot edu Target Milestone: --- Created attachment 39817 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39817&action=edit testcase Hello, I'd like to report an implementation (or even design) problem in GCC. Chapter ยง6.7.9/10 in C11: "If an object that has static or thread storage duration is not initialized explicitly, then: ... if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;" According to this specification, padding bytes should be initialized when the initializer is static. Take a look at this example (say x86_64): ///////////////////////////// struct S { long l; char c; }; void main () { struct S s ={ .l = 0, .c = 0 }; } ///////////////////////////// The developer has carefully initialized all fields with constants. Object "s" is supposed to be fully initialized, i.e., the seven padding bytes right after "s.c" are supposed to be initialized. However, these padding bytes are not initialized in fact. In contrast, LLVM would initialize the padding bytes in such a case. Similarly, when "variables" are used to initialize the fields of "s", padding bytes are not initialized either, such as: ///////////////////////////// struct S s ={ .l = variable1, .c = variable2 }; ///////////////////////////// Such failures to initialize padding bytes will result in many information leaks. We have found many information leaks in the Linux kernel. Here is an example: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4482 More information can be found in our research paper: http://www.cc.gatech.edu/~klu38/publications/unisan-ccs16.pdf The testing program for reproducing the leak is attached. Testing environment: "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)" My suggestion to reliably address this problem is that padding bytes of an object, which are implicitly introduced by compilers, should be zero-initialized upon object allocation. Please let me know if you need more information or any assistance. Best Regards, Kangjie Lu