6.10. Glibc-2.5.1

The Glibc package contains the main C library. This library provides the basic routines for allocating memory, searching directories, opening and closing files, reading and writing files, string handling, pattern matching, arithmetic, and so on.

User Notes: http://wiki.linuxfromscratch.org/hlfs/wiki/glibc

6.10.1. Installation of Glibc

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 Glibc.

Unpack the Linuxthreads add-on:

tar xvf ../glibc-linuxthreads-2.5.tar.bz2

Include the header file for getcwd:

sed 's@#include <unistd.h>@&\n#include <sys/param.h>@' \
    -i.orig sysdeps/unix/sysv/linux/getcwd.c

The some of the tests also need an additional header file included for them to build with linuxthreads:

sed 's/#include <stdio.h>/&\n#include <stdlib.h>/' \
    -i.orig libio/{bug-memstream1,bug-wmemstream1,tst-memstream{1,2}}.c

If you want to install LibIDN then unpack it:

tar vxf ../glibc-libidn-2.5.1.tar.gz
mv -v glibc-libidn-2.5.1 libidn

The following patch is from Glibc-cvs: http://sourceware.org/ml/glibc-cvs/2005-q3/msg00354.html. It uses High Precision Timing to set the Stack Protector guard value if the pseudo-random device fails. This currently only works properly with fairly new CPU's (i686):

patch -Np1 -i ../glibc-2.5.1-ssp_hp-timing-1.patch

The following patch is from Glibc-cvs: http://sourceware.org/ml/glibc-cvs/2006-q4/msg00118.html, and adds __attribute_warn_unused_result__ to additional functions, for more _FORTIFY_SOURCE compiler warnings:

patch -Np1 -i ../glibc-2.5.1-wur-1.patch

The next patch is from Glibc-cvs and fixes the strfry function to handle an empty string:

patch -Np1 -i ../glibc-2.5.1-strfry-1.patch

The next patch is from Glibc-cvs and adds sha256 and sha512 to the crypt library, so it can be used by the Shadow passwords package:

patch -Np1 -i ../glibc-2.5.1-sha512-1.patch

In the vi_VN.TCVN locale, bash enters an infinite loop at startup. It is unknown whether this is a bash bug or a Glibc problem. Disable installation of this locale in order to avoid the problem:

sed -i.orig '/vi_VN.TCVN/d' localedata/SUPPORTED

When running make install, a script called test-installation.pl performs a small sanity test on our newly installed Glibc. However, because our toolchain still points to the /tools directory, the sanity test would be carried out against the wrong Glibc. We can force the script to check the Glibc we have just installed with the following:

sed \
's|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=/lib/ld-linux.so.2 -o|' \
        -i.orig scripts/test-installation.pl

The ldd shell script contains Bash-specific syntax. Change its default program interpreter to /bin/bash in case another /bin/sh is installed as described in the Shells chapter of the BLFS book:

sed 's|@BASH@|/bin/bash|' -i.orig elf/ldd.bash.in

The pt_chown is used to control permissions of /dev/ttyp?. This behavior has been replaced by Unix98 pseudo-terminals in /dev/pts/. This depends on the CONFIG_UNIX98_PTYS kernel driver, which LFS and HLFS highly reccomends everyone to use. The pt_chown is installed SUID root, and since we do not need it there is no reason to install it. Alternatively you can install pt_chown and then remove the SUID bit with a chmod -s /usr/lib/glibc/pt_chown. To prevent pt_chown from being installed run the following command:

sed '/^install.*pt_chown/d' -i.orig login/Makefile

Apply the trampoline patches:

patch -Np1 -i ../glibc-2.5.1-iconvconfig_trampoline-1.patch
patch -Np1 -i ../glibc-2.5.1-localedef_trampoline-1.patch

Apply the PT_PAX_FLAGS patch:

patch -Np1 -i ../glibc-2.5.1-pt_pax-1.patch

The next patch adds the arc4random(), and mkstemps() library functions to libc. arc4random() is used by many packages as a fail-safe way to get a random string. arc4random() is more dependable than accessing /dev/urandom directly because even if /dev/urandom fails to open arc4random() will use gettimeofday() and getpid() to replace the 0's in a large uninitialized array. So even if two applications use arc4random() at the same instant, and the /dev/urandom device is not accessable (like from inside a chroot), arc4random() will return completely different results to each application, and because it is digested by the arcfour cipher the source of the entropy can not be reverse engineered. This means there's no way to go backwards, and get the urandom or getpid() value, from arc4random()'s output, which makes attacking it more difficult. Please note that although this arc4random() is based on both OpenBSD's and NetBSD's implementation, it is not identical. OpenBSD's implementation depends solely on a sysctl entropy source, but in Linux sysctl is optional and can not be depended on. So the arc4random() stir function in this implementation was drastically modified to use multiple entropy sources. As a result, claims made by other arc4random() implementations may not be valid with this implementation. In particular, this implementation can not guarantee the quality of the source entropy, and so it should be used with caution with cryptography. For all other purposes this implementation should be perfectly suitable. mkstemps() is like mkstemp() except that it accepts a suffix argument. Several packages use mkstemps(), such as GCC and Binutils. mkstemps() is included with this patch so it will use arc4random(), instead of the default gettimeofday(). This patch also uses arc4random() in tempname() so it will be used by the mktemp() family of functions, and in strfry(), res_init(), res_mkquery(), and bindrsvprt() to improve the resolver and port number randomization. Additionally, this patch adds the --with-prng-device configure parameter to allow us to specify which pseudo-random device to use for arc4random() and SSP. This patch was rejected upstream because the Glibc team believes it is more suitable in it's own library. However if arc4random() were used in it's own library then the mktemp() and resolver functions in Glibc would not use it. Apply this patch with the following command:

patch -Np1 -i ../glibc-2.5.1-arc4_prng-3.patch

This patch adds the strlcpy and strlcat functions and manual pages to Glibc. A paper written about these functions is available here: http://www.courtesan.com/todd/papers/strlcpy.html. The Glibc project has refused to add these functions, and that mail tread starts here: http://sources.redhat.com/ml/libc-alpha/2000-08/msg00052.html. Linus Torvalds has added a similar function to the Linux kernel, and that mail thread is here: http://lwn.net/Articles/33814/. The strlcpy and strlcat functions are replacements for the strncpy and strncat. The controversy of these functions is that strlcpy and strlcat copy the source data to the destination buffer until the destination is full, and discards the rest of the data if there is any. This means that these functions will never overflow. The basis for the Glibc team's refusal to add these functions is that they silently hide programing errors, and they have a higher performance hit than strncpy and strncat. These functions should not be needed in a perfect world, but were invented to deal with the real world. Many packages will use these functions if they are found, such as Perl and many BLFS packages. These functions do reduce buffer overflows, and so they are recommended. After installing this patch no other effort is needed to use it. Packages will use autotools to detect whether they are available or not:

patch -Np1 -i ../glibc-2.5.1-strlcpy_strlcat-1.patch

The asprintf(3) and vasprintf(3) functions are GNU extentions, not defined by C or Posix standards. In Glibc these functions leave (char **strp) undefined (it may, or may not, be defined) after an error. This patch resets (char **strp) to NULL after an error, for sanity. This patch, and the behavior it sets, was reviewed and discussed on the Glibc mailing list, and appeared to be accepted, and then it looks like it was forgotten about. This patch is optional, and nothing will depend on it, but it fixes a bug prone behaviour of these library functions. Apply this patch with the following command:

patch -Np1 -i ../glibc-2.5.1-asprintf_reset2null-1.patch

This patch adds the issetugid() function, which is a front-end to the __libc_enable_secure() dynamic linker private function. This function reports whether the program is running with matching real and effective ID's, or not, to determine whether the program is running with set-uid or set-gid privileges. Many packages will search for issetugid() and use it if found. This is safer than allowing each program to determine privileges itself because it is tested at a lower level which is not manipulatable by the user. Apply this patch with the following command:

patch -Np1 -i ../glibc-2.5.1-issetugid-1.patch

Add MUDFLAP_OPTIONS to the list of environment variables which are removed by libc for suid programs. This will keep local users, including root, from disabling bounds checking on suid programs linked to libmudflap.so:

sed 's/#define UNSECURE_ENVVARS.*/&\
  "MUDFLAP_OPTIONS\\0" \\/' -i.orig sysdeps/generic/unsecvars.h

Glibc's configure script will fail several tests because -fstack-protector[-all] and -nostdlib are being used together and the conftest program is not getting linked to libc.so, which causes the SSP symbols to be missing and the conftest test program fails. This won't be a problem after configure is run though. Fix configure so its tests pass correctly:

sed 's/-nostdlib/& -fno-stack-protector/g' -i.orig configure

The nscd program will be compiled with -fstack-protector by Glibc, but this will override -fstack-protector-all in our GCC specs. nscd can compile with -fstack-protector-all, so fix that:

sed 's/fstack-protector/&-all/' -i.orig nscd/Makefile

The ldconfig program is statically linked. The next command adds compiler options so it will not be built as PIC unnessessarily:

sed 's/CFLAGS-ldconfig.c =/& -fno-PIC -fno-PIE/' \
    -i.orig elf/Makefile

The Glibc documentation recommends building Glibc outside of the source directory in a dedicated build directory:

mkdir -v ../glibc-build
cd ../glibc-build

Prepare Glibc for compilation (you may want to add --enable-all-warnings):

../glibc-2.5.1/configure --prefix=/usr \
    --libexecdir=/usr/lib/glibc --enable-kernel=2.4.0 \
    --enable-stackguard-randomization --enable-bind-now \
    --disable-profile --enable-add-ons=linuxthreads,libidn \
    --disable-sanity-checks --with-prng-device=/dev/erandom

The meaning of the configure options:

--enable-stackguard-randomization

This tells Glibc to initialize __stack_chk_guard canary with a random number at program start, instead of a static number.

--with-prng-device=/dev/erandom

This option tells arc4random and SSP which pseudo-random device to use. /dev/erandom is ideal but it depends on the Frandom kernel patch. /dev/urandom can also be used, but this is discouraged unless you run a random number generator daemon so real entropy is always available to cryptographic applications.

The Glibc libraries can not be built with -fstack-protector[-all], -D_FORTIFY_SOURCE, or -Wl,-z,now. The --enable-bind-now configure option will add -Wl,-z,now where it can be used. We can control compiler options used during the build with the configparms file. First we will build the libraries. The following command will set up the configparms file to only build the libraries, and to disable options we can't use:

cat > configparms << "EOF"
build-programs=no
CC = gcc -fPIC -fno-stack-protector -U_FORTIFY_SOURCE -nonow -nopie
CXX = g++ -fPIC -fno-stack-protector -U_FORTIFY_SOURCE -nonow -nopie
EOF

Compile the libraries:

make

Glibc links startfiles explicitly. The following will modify the link command used, so that the programs will be linked to the sharable startfiles, and explicitly use -fPIE. The sln is another statically linked program, so options are added so it is not compiled as PIC:

cat > configparms << "EOF"
CC = gcc -fPIE -fstack-protector-all -D_FORTIFY_SOURCE=2
CXX = g++ -fPIE -fstack-protector-all -D_FORTIFY_SOURCE=2
CFLAGS-sln.c += -fno-PIC -fno-PIE
+link = $(CC) -nostdlib -nostartfiles -fPIE -pie -o $@ \
 $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
 -Wl,-z,combreloc -Wl,-z,relro -Wl,-z,now $(hashstyle-LDFLAGS) \
 $(addprefix $(csu-objpfx),S$(start-installed-name)) \
 $(+preinit) `$(CC) --print-file-name=crtbeginS.o` \
 $(filter-out $(addprefix $(csu-objpfx),start.o \
  $(start-installed-name))\
 $(+preinit) $(link-extra-libs) \
 $(common-objpfx)libc% $(+postinit),$^) \
 $(link-extra-libs) $(link-libc) `$(CC) --print-file-name=crtendS.o` $(+postinit)
EOF

Any other compiler hardening options are passed by default, so they do not need to be added to the configparms file.

Now run make again to build Glibc's programs:

make

To test the results first create a new configparms file to disable most hardening options:

cat > configparms << "EOF"
CC = gcc -fPIC -fno-stack-protector -U_FORTIFY_SOURCE -nonow -nopie
CXX = g++ -fPIC -fno-stack-protector -U_FORTIFY_SOURCE -nonow -nopie
EOF

Then run the test suite:

make -k check 2>&1 | tee glibc-check-log
grep -n Error glibc-check-log

The Glibc test suite depends on features of the host system kernel. Under ideal conditions all tests, except “posix/annexc.out (ignored)”, should pass. The “elf/check-localplt” test often fails because there are added symbols in libc.so which were unexpected. This is caused by the GCC options we use, and Glibc patches.

You can also run make check-abi if you like. This checks ELF dynamic symbol tables against expected values. See: http://sourceware.org/ml/libc-hacker/2002-12/msg00048.html. This testsuite produces a long list of errors, which occure even on ideal vanilla systems.

Though it is a harmless message, the install stage of Glibc will complain about the absence of /etc/ld.so.conf. Prevent this warning with:

touch /etc/ld.so.conf

Install the package:

make install

Install the arc4random() and mkstemps() manual pages:

install -v -m0644 ../glibc-2.5.1/manual/{arc4random,mkstemps}.3 \
    /usr/share/man/man3/

Install the issetugid() manual page:

install -v -m0644 ../glibc-2.5.1/manual/issetugid.3 \
    /usr/share/man/man3/

Move the static libs.:

install -vd /usr/lib/static/
mv -v /usr/lib/{libbsd-compat,libg,libieee,libmcheck}.a /usr/lib/static/
mv -v /usr/lib/{libBrokenLocale,libanl,libcrypt}.a /usr/lib/static/
mv -v /usr/lib/{libm,libnsl,libpthread,libresolv}.a /usr/lib/static/
mv -v /usr/lib/{librpcsvc,librt,libutil}.a /usr/lib/static/

The libc_nonshared.a library is needed to compile just about everything. The libpthread_nonshared.a library is needed whenever anything links to libpthread.so. libc.a is needed for GCC's test suite, libdl.a is needed for Binutils test suite, and they can be moved after they're installed.

To install all the locales use:

make localedata/install-locales

To install just what the GCC test need use the following commands instead of the previous make localedata/install-locales:

install -d /usr/lib/locale
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i ja_JP -f EUC-JP ja_JP

6.10.2. Configuring Glibc

The /etc/nsswitch.conf file needs to be created because, although Glibc provides defaults when this file is missing or corrupt, the Glibc defaults do not work well with networking. The time zone also needs to be set up.

Create a new file /etc/nsswitch.conf by running the following:

cat > /etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

protocols: files
services: files
ethers: files
rpc: files

# End /etc/nsswitch.conf
EOF

To determine the local time zone, run the following script:

tzselect

After answering a few questions about the location, the script will output the name of the time zone (e.g., EST5EDT or Canada/Eastern). Then create the /etc/localtime file by running:

cp -v --remove-destination /usr/share/zoneinfo/[xxx] \
    /etc/localtime

Replace [xxx] with the name of the time zone that the tzselect provided (e.g., Canada/Eastern).

The meaning of the cp option:

--remove-destination

This is needed to force removal of the already existing symbolic link. The reason for copying the file instead of using a symlink is to cover the situation where /usr is on a separate partition. This could be important when booted into single user mode.

6.10.3. Configuring the Dynamic Loader

By default, the dynamic loader (/lib/ld-linux.so.2) searches through /lib and /usr/lib for dynamic libraries that are needed by programs as they are run. However, if there are libraries in directories other than /lib and /usr/lib, these need to be added to the /etc/ld.so.conf file in order for the dynamic loader to find them.

Create a new file /etc/ld.so.conf by running the following:

echo "/usr/local/lib" > ld.so.conf.new
install -m644 ld.so.conf.new /etc/ld.so.conf

6.10.4. Contents of Glibc

Installed programs: catchsegv, gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, locale, localedef, mtrace, nscd, pcprofiledump, pt_chown, rpcgen, rpcinfo, sln, sprof, tzselect, xtrace, zdump, and zic
Installed libraries: ld.so, libBrokenLocale.{a,so}, libSegFault.so, libanl.{a,so}, libbsd-compat.a, libc.{a,so}, libcidn.so, libcrypt.{a,so}, libdl.{a,so}, libg.a, libieee.a, libm.{a,so}, libmcheck.a, libmemusage.so, libnsl.a, libnss_compat.so, libnss_dns.so, libnss_files.so, libnss_hesiod.so, libnss_nis.so, libnss_nisplus.so, libpcprofile.so, libpthread.{a,so}, libresolv.{a,so}, librpcsvc.a, librt.{a,so}, libthread_db.so, and libutil.{a,so}

Short Descriptions

catchsegv

Can be used to create a stack trace when a program terminates with a segmentation fault

gencat

Generates message catalogues

getconf

Displays the system configuration values for file system specific variables

getent

Gets entries from an administrative database

iconv

Performs character set conversion

iconvconfig

Creates fastloading iconv module configuration files

ldconfig

Configures the dynamic linker runtime bindings

ldd

Reports which shared libraries are required by each given program or shared library

lddlibc4

Assists ldd with object files

locale

Prints various information about the current locale

localedef

Compiles locale specifications

mtrace

Reads and interprets a memory trace file and displays a summary in human-readable format

nscd

A daemon that provides a cache for the most common name service requests

pcprofiledump

Dumps information generated by PC profiling

pt_chown

A helper program for grantpt to set the owner, group and access permissions of a slave pseudo terminal

rpcgen

Generates C code to implement the Remote Procecure Call (RPC) protocol

rpcinfo

Makes an RPC call to an RPC server

sln

A statically linked ln program

sprof

Reads and displays shared object profiling data

tzselect

Asks the user about the location of the system and reports the corresponding time zone description

xtrace

Traces the execution of a program by printing the currently executed function

zdump

The time zone dumper

zic

The time zone compiler

ld.so

The helper program for shared library executables

libBrokenLocale

Used internally by Glibc as a gross hack to get broken programs (e.g., some Motif applications) running. See comments in glibc-2.5.1/locale/broken_cur_max.c for more information

libSegFault

The segmentation fault signal handler, used by catchsegv

libanl

An asynchronous name lookup library

libbsd-compat

Provides the portability needed in order to run certain Berkeley Software Distribution (BSD) programs under Linux

libc

The main C library

libcidn

Used internally by Glibc for handling internationalized domain names in the getaddrinfo() function

libcrypt

The cryptography library

libdl

The dynamic linking interface library

libg

Dummy library containing no functions. Previously was a runtime library for g++

libieee

Linking in this module forces error handling rules for math functions as defined by the Institute of Electrical and Electronic Engineers (IEEE). The default is POSIX.1 error handling

libm

The mathematical library

libmcheck

Turns on memory allocation checking when linked to

libmemusage

Used by memusage to help collect information about the memory usage of a program

libnsl

The network services library

libnss

The Name Service Switch libraries, containing functions for resolving host names, user names, group names, aliases, services, protocols, etc.

libpcprofile

Contains profiling functions used to track the amount of CPU time spent in specific source code lines

libpthread

The POSIX threads library

libresolv

Contains functions for creating, sending, and interpreting packets to the Internet domain name servers

librpcsvc

Contains functions providing miscellaneous RPC services

librt

Contains functions providing most of the interfaces specified by the POSIX.1b Realtime Extension

libthread_db

Contains functions useful for building debuggers for multi-threaded programs

libutil

Contains code for “standard” functions used in many different Unix utilities