October 13, 2004
This article was contributed by John Richard Moser
Linux does not host the same applications as the more popular operating
systems; it does not cater to the same host of bugs those applications
provide to allow attackers to easily gain privileged access to the system.
Still, if the same classes of bugs exist in Linux applications, the same
problems arise. Linux is vulnerable to the same exploits as any other
operating system when bugs exist to facilitate those exploits.
Most popular Linux distributions do not make use of available security
technologies that would deflect a large number of these attacks. There are
technologies available today that allow the maintainers of distributions
such as Gentoo, Debian, or Mandrake to make the system more resilient if
not virtually invulnerable to these exploitable bugs. These technologies
are open source, GPL licensed solutions to the future problems that Linux
will face as it gains popularity.
There are many transparent security technologies available that maintainers
could use to improve the security of a Linux distribution, such as Stack Smash
Protection, PaX, and Position
Independent Executables (PIE). These, such as can be safely and easily
integrated with any distribution to improve security without altering the
users' experience or administration of the system.
Stack Smash Protection
Stack Smash Protection is a method of detection and mitigation of stack
based buffer overflow bugs in programs. There are several implementations;
the one focused on here is
IBM's Stack
Smash Protector (SSP), formerly known as ProPolice. SSP prevents stack
based buffer overflow bugs from being used to exploit programs in many
cases.
A fair number of security exploits begin with stack based buffer overflows.
SSP rearranges local variables to put character arrays at the highest
address and copies pointers passed to the function to new local variables
below these arrays. This prevents a wide range of overflow based attacks.
It uses a strategically placed local variable known as a "canary" or "guard
value" to check for overflows.
SSP is implemented as a compiler patch to gcc. This patch alters the way
functions are generated so that they check for buffer overflows. It can be
used via the -fstack-protector and -fstack-protector-all
switches, or by passing --enable-stack-protector to the
configure script when building gcc. In either case,
-fno-stack-protetctor[-all] explicitly disables the
protection.
There are still
some
cases which SSP cannot catch, such as bugs affecting structures with
vulnerable layouts; but it is definitely a powerful tool for preventing
exploitation of many programming bugs. It may also expose some simple
programming bugs, such as those which overflow a buffer by a few bytes.
These bugs cause programs to crash during normal operation with SSP.
SSP was developed by Hiroaki Etoh and Kunikazu Yoda of the IBM Research
Division, based on StackGuard. It was
originally outlined in a paper
by its authors. StackGuard was developed by Immunix Inc., and first appeared in 1998
or earlier. There have also been other papers
examining stack smash protection techniques and implementation.
PaX
PaX is a patch to the Linux kernel source tree to implement memory
protections which make certain classes of exploits difficult or impossible.
Depending on architecture, PaX may have a very low or insignificant
overhead. It is a powerful tool for preventing a great many potential
exploits.
The Exec Shield (ES) technology contributed by Red Hat is somewhat similar
to PaX; however, PaX
supplies greater control over protections on individual binaries, as well
as greater accuracy in its NX emulation on x86 architectures. ES has been
compared to PaX on Wikipedia.
Unless otherwise specified, full PaX with all features enabled except
"Disallow ELF text relocations" will be discussed here.
PaX is a very feature rich technology. Instead of targeting a specific
attack vector, PaX targets entire classes of exploits. Attacks using
standard code injection are essentially impossible to successfully perform
on a task running under full PaX restrictions; many of the more complex
attacks are extremely difficult and often impossible to guarantee. Failed
attacks result in the immediate termination of the program.
PaX guarantees that no memory is both writable and executable. The system
administrator may deny all programs permission to use mprotect() to
transition to a state where the page may be executed at any time after it
could have been written to. It may emulate an NX bit to accomplish this;
this is done on x86 with measurable but low overhead.
PaX also allows full Address Space Layout Randomization (ASLR). ASLR
allows the stack, heap, mmap(), and even the .text of ET_EXEC executables
to be mapped into randomly chosen bases in Virtual Memory (VM) space. In
the absence of an information leak, an attacker would need to essentially
guess at where any needed target data is in memory.
Some programs malfunction under PaX. Usually these programs expect
behavior contrary to what PaX provides, and upon attempting to execute
certain logic, PaX terminates them as if it had detected an exploit. PaX
allows binaries to be "marked" with tools available to the system
administrator to disable any individual protection supplied by PaX.
PaX was created by an anonymous author, originally supplying NX support
based on an observation about the x86 architecture made by the plex86
project. Other features such as ASLR were implemented later. PaX first
appeared in 2000, and was later incorporated into the grsecurity project.
The PaX project supplies much documentation, and Wikipedia
features an article about
PaX.
Position Independent Executables
Position Independent Executables, or PIE, are executables compiled as
Position Independent Code (PIC). PIC is usually slower than fixed position
code; however, it can be easily relocated in memory. PIE allows the safe
and efficient randomization of the base of executable binaries in VM by PaX
or ES, preventing an attacker from knowing beforehand where preexisting
code is in memory.
Compiling PIE binaries is done by passing gcc the -fPIC or
-fPIE switches;
linking them is done by passing -pie to gcc or to the linker. The
-fPIE
switch only works with gcc 3.4, but -fPIC will work for all.
Regardless of
which switch is used, the output is an executable ET_DYN binary.
Using PIE, the code in executable binaries suffers
measurable overhead,
the magnitude of which varies between CPU architectures. On x86, this is
approximately 1%; whereas on x86_64, the overhead is approximately 0.01%.
Because this overhead is not applied everywhere, it can usually be said to
be negligible on any architecture in relation to PIE.
Deployment
Many security focused open source operating systems deploy these or similar
technologies. OpenBSD supplies its own
PaX-type system, W^X; OpenBSD also uses SSP; but apparently does not supply a PIE base.
Hardened Gentoo and Adamantix supply PaX, SSP, and PIE;
along with other, more visible technologies such as SELinux or RSBAC. It
is left up to speculation why the most popular Linux distributions do not
supply the transparent features, although there is effort to persuade Debian to use these, by the Debian: Secure by Default and
the Hardened Debian
projects.
(
Log in to post comments)