NOTE: Intel® Memory Protection Extensions (Intel® MPX) have been deprecated and are not available on all future processors.
Invalid memory access problem is commonly found in many C/C++ programs and leads to time consuming debugging, program instability and vulnerability. Many attacks exploit software bugs related to inappropriate memory accesses caused by buffer overflow (or buffer overruns). Existing set of techniques/tools to find such memory bugs in the programs and defend them from the attacks are software only solutions which result in poor performance of the protected code.
Intel® is introducing a new ISA extension called Intel® Memory Protection Extensions (Intel® MPX) (see latest Programming Reference manual posted here under Related Specifications) to be used for memory protection in applications with low performance overhead. To get the advantage of new extension, changes are required in the OS kernel, binutils, compiler, system libraries support.
This paper describes changes in GNU Binutils, GCC and Glibc to support Intel® MPX.
Intel® MPX introduces new registers called bound registers to hold bounds for a pointer and instructions to manipulate those registers (for details see the Programming Reference). Therefore the first step is to implement support for new hardware features in binutils and the GCC.
The second step in Intel® MPX support is implementation of Intel® MPX instrumentation pass in the GCC compiler which is responsible for instrumenting all memory accesses with pointer checks. Compiler changes for runtime bound checks include:
Dynamically created objects in heap using memory allocators need to set bounds for objects (buffers) at allocation time. So the next step is to add Intel® MPX support into standard memory allocators in Glibc.
To have the full protection, an application has to use libraries compiled with Intel® MPX instrumentation. It means we had to compile Glibc with the Intel® MPX enabled GCC compiler because it is used in most applications. Also we had to add Intel® MPX instrumentation to all the necessary Glibc routines (e.g. memcpy) written on assembler.
We introduce new option –fmpx in the GCC to utilize Intel® MPX instructions. Also binutils with Intel® MPX enabled should be used to get binaries with memory protection.
Consider following simple test for MPX compiled program:
int main(int argc, char* argv)
Snippet of the original assembler output (compiled with -O2):
movslq %edi, %rdi
movl -120(%rsp,%rdi,4), %eax // memory access buf[argc]
Compile test as follows: mpx-gcc/gcc test.c -fmpx –O2.
Resulted assembler snippet:
movl $399, %edx // load array length to edx
movslq %edi, %rdi // rdi contains value of argc
leaq -104(%rsp), %rax // load start address of buf to rax
bndmk (%rax,%rdx), %bnd0 // create bounds for buf
bndcl (%rax,%rdi,4), %bnd0 // check that memory access doesn’t violate buf’s low bound
bndcu 3(%rax,%rdi,4), %bnd0 // check that memory access doesn’t violate buf’s upper bound
movl -104(%rsp,%rdi,4), %eax // original memory access
Code looks pretty clear. Note only that we added displacement 3 for upper bound checking since we have 4 byte (integer) access here.
Another simple example demonstrates using of bndldx and bndstx instructions.
extern int * p;
extern int * q;
int foo( int c)
q = p;
After compilation with –O2 –fmpx we have such piece of assembler code:
movq p(%rip), %rax
movslq %edi, %rdi
bndldx p(,%rax), %bnd0 // load bounds for pointer p into bnd0
movq %rax, q(%rip) // q=p
bndstx %bnd0, q(,%rax) // we need now to update bound information for q
leaq (%rax,%rdi,4), %rax
bndcl (%rax), %bnd0
bndcu 3(%rax), %bnd0
movl (%rax), %eax
Several Intel® MPX specific compiler options besides –fmpx were introduced in the compiler. Most of them, like -fmpx-check-read and -fmpx-check-write, control number of inserted runtime bound checks. Also developers always can use intrinsics to insert Intel® MPX instructions manually. To see full set of Intel® MPX specific options and intrinsics added to the compiler check GCC Wiki page
Currently GCC compiler sources with Intel® MPX support is available in a separate branch in common GCC SVN repository. See GCC SVN page for details.
Currently no hardware with Intel® MPX ISA is available but it is always possible to use Intel® SDE instead, which can be downloaded from http://software.intel.com/en-us/articles/intel-software-development-emulator
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice.
Notice revision #20110804