6.12.1. Installation of GCC
This package is known to have issues when its default optimization
flags (including the -march
and -mtune options) are
changed. If any environment variables that override default
optimizations have been defined, such as CFLAGS and CXXFLAGS,
unset them when building GCC.
Unpack the binutils-2.18, gcc-core-4.2.1, gcc-g++-4.2.1, and
gcc-testsuite-4.2.1 source packages but do not change directory.
Then combine the two packages to the same directory with the
following commands:
mv -v gcc-4.2.1/ butterfly-toolchain
mv -v binutils-2.18 butterfly-toolchain/
cd butterfly-toolchain
Next fix the problem with the cp-demangle.c:
cp -v libiberty/cp-demangle.c binutils-2.18/libiberty/cp-demangle-gcc.c
sed 's@libiberty/cp-demangle@&-gcc@' -i.orig libstdc++-v3/libsupc++/Makefile.in
rm -rf libiberty/
ln -vs binutils-2.18/{bfd,binutils,gas,gprof,ld,libiberty,opcodes} .
Disable -Werror in libgomp:
sed 's/-Werror//' -i.orig libgomp/configure
Patch Binutils for PT_PAX_FLAGS:
cd binutils-2.18/
patch -Np1 -i ../../binutils-2.18-pt_pax-1.patch
cd ..
Add the patch for __strncat_chk
compile time checking:
patch -Np1 -i ../gcc-4.2.1-strncat_chk-1.patch
Apply the -D_FORTIFY_SOURCE=2 GCC specs patch:
patch -Np1 -i ../gcc-4.2.1-fortify_source-1.patch
Apply the -fstack-protector-all GCC specs
patch:
patch -Np1 -i ../gcc-4.2.1-fstack_protector-1.patch
Apply the -fPIE patch:
patch -Np1 -i ../gcc-4.2.1-fpie-1.patch
Apply these patches for uClibc support. The locale patch is needed
even if you have disabled locale support:
cd binutils-2.18/
patch -Np1 -i ../../binutils-2.18-uClibc_conf-1.patch
cd ../
patch -Np1 -i ../gcc-4.2.1-uClibc_conf-1.patch
patch -Np1 -i ../gcc-4.2.1-uClibc_locale-1.patch
Use this command to hardcode LIBS="-lintl":
sed 's/%{shared:-lc}/%{!nointl: -lintl} &/' \
-i gcc/config/linux.h
The mudflap debugging feature included with GCC will normally allow
a program to continue running during violations to give the user
more information. The following command will change this default
behaviour so libmudflap will send an
ABRT signal to abort the program. This can be reset with the
MUDFLAP_OPTIONS environment variable.
Please keep in mind that mudflap is a debugging feature, and was
not intended as a security feature, and is being implemented like
this here because this is better than not using it at all. This
modification can be circumvented by a user setting the LD_PRELOAD environment variable to load an alternate
libmudflap library:
sed 's/violation_mode = viol_nop/violation_mode = viol_abort/' \
-i.orig libmudflap/mf-runtime.c
Create a separate build directory again:
mkdir -v ../butterfly-build
cd ../butterfly-build
Prepare for compilation:
../butterfly-toolchain/configure --prefix=/usr \
--libexecdir=/usr/lib --enable-shared \
--enable-threads=posix --enable-__cxa_atexit \
--enable-clocale=gnu --enable-languages=c,c++ \
--enable-checking --disable-werror --disable-bootstrap
The meaning of the configure options:
-
--disable-werror
-
The -Werror option can not be
used when building this toolchain because _FORTIFY_SOURCE
will cause warnings which can not be fixed. In particular,
warnings about variable size buffers.
Compile the package:
make tooldir=/usr
The meaning of the make parameter:
-
tooldir=/usr
-
Normally, the tooldir (the directory where the executables
will ultimately be located) is set to $(exec_prefix)/$(target_alias). For
example, i686 machines would expand that to /usr/i686-pc-linux-gnu. Because this is a
custom system, this target-specific directory in /usr is not required. $(exec_prefix)/$(target_alias) would be
used if the system was used to cross-compile (for example,
compiling a package on an Intel machine that generates code
that can be executed on PowerPC machines).
To test the results:
make -k check
There is an SSP test in gcc.misc-tests/. The testsuite will be very bad.
SSP and PIC need to be disabled in CFLAGS_FOR_TARGET, and
-L/usr/lib/static probably needs to be added so static libraries
can be used.
Install the package:
make tooldir=/usr install
Make symlinks for _FORTIFY_SOURCE headers. These headers are only
used if _FORTIFY_SOURCE is defined, so if you use -U_FORTIFY_SOURCE you will get vanilla behaviour
like normal:
ln -vs ssp/{ssp,stdio,string,unistd}.h \
`dirname $(gcc -print-libgcc-file-name)`/include/
If you plan to link suid packages to libmudflap then you need to move the mudflap
libraries to /lib with the following
command:
mv -v /usr/lib/libmudflap{,th}.so* /lib
ln -vsf ../../lib/libmudflap.so.0 /usr/lib/libmudflap.so
ln -vsf ../../lib/libmudflapth.so.0 /usr/lib/libmudflapth.so
Move the static libraries installed by GCC:
mv -v /usr/lib/{libsupc++,libstdc++}.a /usr/lib/static/
mv -v /usr/lib/{libbfd,libiberty,libmudflap,libmudflapth}.a /usr/lib/static
mv -v /usr/lib/{libopcodes,libssp,libssp_nonshared}.a /usr/lib/static
mv -v /usr/lib/gcc/$(gcc -dumpmachine)/4.2.1/libgcov.a /usr/lib/static/
mv -v /usr/lib/libstdc++_pic.a /usr/lib/static/
Move libc.a and libdl.a from the C library package:
mv -v /usr/lib/{libc,libdl}.a /usr/lib/static
Some packages expect the C PreProcessor to be installed in the
/lib directory. To support those
packages, create this symlink:
ln -vs ../usr/bin/cpp /lib
Many packages use the name cc to call the C compiler. To
satisfy those packages, create a symlink:
ln -vs gcc /usr/bin/cc
Install the libiberty header file
that is needed by some packages:
install -v -m0644 ../butterfly-toolchain/include/libiberty.h \
/usr/include
Important
This test program will cause fgets(3) to have a buffer overflow.
This regression program is from the Netbsd project. This is an
example where static code checking will not detect a problem,
because the overflow is caused by user input at run time. The
only problem that is reported by static code analysis programs,
like Splint or
the -Wextra option, is
that the int argc paramter is
unused:
cat > fgets-overflow.c << "EOF"
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char b[10];
int len = atoi(argv[1]);
if ((fgets(b, len, stdin)) != b)
return 1;
(void)printf("%s\n", b);
return 0;
}
EOF
First test SSP:
gcc -o fgets-overflow fgets-overflow.c -U_FORTIFY_SOURCE
echo abcdefghijklm | ./fgets-overflow 14
This should return:
*** stack smashing detected ***: ./fgets-overflow terminated
Aborted
Then test _FORTIFY_SOURCE:
gcc -o fgets-overflow fgets-overflow.c -fno-stack-protector
echo abcdefghijklm | ./fgets-overflow 14
This should return:
*** buffer overflow detected ***: ./fgets-overflow terminated
Aborted
Both _FORTIFY_SOURCE and SSP will abort this program if the
program's argument (14 in the above example) is more than 10.
The next program is a simple strcpy(3) overflow, and is an
example where static code analysis will catch the problem:
cat > strcpy-overflow.c << "EOF"
#include <string.h>
int main()
{
char buf[2];
strcpy(buf,"12345");
return 0;
}
EOF
gcc -o strcpy-overflow strcpy-overflow.c
This should display:
strcpy-overflow.c: In function 'main':
strcpy-overflow.c:5: warning: call to __builtin___strcpy_chk will
always overflow destination buffer
Here the _FORTIFY_SOURCE feature is warning that the compiler
knows in advance that strcpy(3) will overflow. Try to run the
program:
./strcpy-overflow
This should return:
*** buffer overflow detected ***: ./fortify-test terminated
Aborted
In this fortify-test program the strcpy() function was replaced
with the __strcpy_chk() function at compile time, when the
warning was generated. The __strcpy_chk() function then aborted
the program at run time when a buffer overflow was detected.
This particular program can also be used to test the Stack
Smashing Protector. Recompile this program with optimizations
disabled and FORTIFY_SOURCE enabled, which will override the GCC
specs, simply to show that FORTIFY_SOURCE only works with
optimizations:
gcc -o strcpy-overflow strcpy-overflow.c -O0 -D_FORTIFY_SOURCE=2
Then run it:
./strcpy-overflow
This should return:
*** stack smashing detected ***: ./ssp-test terminated
Aborted