$ hg id
3736bf94535c+ tip
A standard Python build does not take a proactive approach to integrating with platform security measures. Attepting to add the measures results in a failed build.
For example:
export CC=/usr/bin/gcc
export CXX=/usr/bin/g++
export CFLAGS="-fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2"
export CXXFLAGS="-fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2"
export LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,noexecheap -Wl,-z,now -Wl,-z,relro"
will configure properly, but will fail to build.
The idea is to build executables with {-fPIE,-pie} and build shared objects with {-fPIC,-shared}. Both executables and shared objects get the remaining platform security integrations like stack protectors and NX stacks/heaps.
In the case an object file is used for both an executable and shared object, it should be compiled with -fPIC (and linking will include -pie or -shared as required). Its OK to use -fPIC in place of -fPIE. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52885 for details.
*****
Examining the failed compile:
/usr/bin/gcc -pthread -shared -pie -Wl,-z,noexecstack -Wl,-z,noexecheap -Wl,-z,now -Wl,-z,relro -pie -Wl,-z,noexecstack -Wl,-z,noexecheap -Wl,-z,now -Wl,-z,relro -pie -Wl,-z,noexecstack -Wl,-z,noexecheap -Wl,-z,now -Wl,-z,relro -fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.4/home/jwalton/Desktop/cpython-checkout/Modules/_struct.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -o build/lib.linux-x86_64-3.4/_struct.cpython-34m.so
So, autotools tried to add both -pie (for executables) and -shared (for shared objects). Fail.
The same problem occurs with _struct.cpython-34m.so, _ctypes_test.cpython-34m.so, array.cpython-34m.so, cmath.cpython-34m.so, math.cpython-34m.so, time.cpython-34m.so, _datetime.cpython-34m.so, _random.cpython-34m.so, _bisect.cpython-34m.so, ...
*****
I know I can omit -pie from CFLAGS and CXXFLAGS:
export CC=/usr/bin/gcc
export CXX=/usr/bin/g++
export CFLAGS="-fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2"
export CXXFLAGS="-fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2"
export LDFLAGS="-Wl,-z,noexecstack -Wl,-z,noexecheap -Wl,-z,now -Wl,-z,relro"
but then I have to manually add -pie to Makefile lines with $BUILDPYTHON (and others, like _testembed and _freeze_importlib):
$(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
$(LINKCC) -pie $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
...
*****
Examining an executable produced by the modified Makefil with Tobias Klein's Checksec (http://www.trapkit.de/tools/checksec.html) shows the platform security integrations were successfully applied:
$ checksec.sh --file ./python
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH ./python
*****
Running `make test` with the security integrations worked as expected, and did not result in any adverse behavior (like an abrupt shutdown).
*****
It would be great if Python tested for features like ASLR for executables, and simply added {-fPIE,-pie} as available. The same is true for the other security offerings (_FORTIFY_SOURCE should be added to Release builds only). |