mNo edit summary |
m (fix typos!) |
||
Line 113: | Line 113: | ||
|- | |- | ||
| [[#Tamper Resistant Logs|Tamper Resistant Logs]] || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#98fd98" | Y || style="background:#98fd98" | Y || style="background:#98fd98" | Y | | [[#Tamper Resistant Logs|Tamper Resistant Logs]] || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#98fd98" | Y || style="background:#98fd98" | Y || style="background:#98fd98" | Y | ||
|- | |||
| [[#Overflow checking in new operator|Overflow checking in new operator]] || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#ffff00" | N || style="background:#98fd98" | Y || style="background:#98fd98" | Y || style="background:#98fd98" | Y | |||
|- | |- | ||
|} | |} | ||
Line 237: | Line 239: | ||
using the xattrs available to most modern filesystems. This | using the xattrs available to most modern filesystems. This | ||
reduces the possible misuse of vulnerable setuid applications. The kernel | reduces the possible misuse of vulnerable setuid applications. The kernel | ||
provides the support and the user-space tools are | provides the support and the user-space tools are available in the | ||
standard repositories. | standard repositories. | ||
Programmes have been vulnerable to set-UID, there is no need for having root | Programmes have been vulnerable to set-UID, there is no need for having root | ||
process to run, it is logical to provide to | privileges every time for a process to run, it is logical to provide to minimum | ||
programme to run effectively. With the normal set-UID approach programmes would run more than the | set of privileges to programme that can enable the programme to run | ||
required, increasing the risk of | effectively. With the normal set-UID approach programmes would run more than | ||
known as file capability implemented in fs/exec.c in Kernel itself. | the privileges required, increasing the risk of Privilege Escalation. Enabling | ||
Capabilities to programme has been started since kernel 2.6.24 known as file | |||
capability implemented in fs/exec.c in Kernel itself. | |||
Common capabilities are implemented in security/commoncap.c | Common capabilities are implemented in security/commoncap.c | ||
Line 264: | Line 268: | ||
|} | |} | ||
==== Modifying Filesystem | ==== Modifying Filesystem Capabilities ==== | ||
There is no specific system call provided by the linux to modify filesystem capabilities. | There is no specific system call provided by the linux to modify filesystem capabilities. | ||
But as its implemented as inode getxattr() , fsetxattr system calls can be used. | But as its implemented as inode getxattr() , fsetxattr system calls can be used. | ||
Here "$" means normal user and "#" means root user. | Here "$" means normal user and "#" means root user. Let's take 'ping' as working example | ||
to show how capabilities work. | to show how capabilities work. | ||
Line 306: | Line 310: | ||
rtt min/avg/max/mdev = 0.170/0.170/0.170/0.000 ms | rtt min/avg/max/mdev = 0.170/0.170/0.170/0.000 ms | ||
from that it can be concluded that, ping requires more | from that it can be concluded that, ping requires more privileges then a normal user for specially | ||
crafted network packets, so while running with 'root' user it works as 'root' has all effective | crafted network packets, so while running with 'root' user it works as 'root' has all effective | ||
capabilities. In the Linux Kernel there is a check which sees if application is capable, which means | capabilities. In the Linux Kernel there is a check which sees if application is capable, which means | ||
to run it should have effective capability for CAP_NET_RAW. | to run it should have effective capability for CAP_NET_RAW. | ||
Using set-UID root makes 'ping' over privileged, if buffer overflow is detected | |||
do local | then attacker could do local privilege escalation giving back shell. | ||
Line 366: | Line 370: | ||
User namespaces allow per-namespace mappings of user and group IDs. This means | User namespaces allow per-namespace mappings of user and group IDs. This means | ||
that a process' | that a process' user and group IDs inside a user namespace can be different | ||
from its IDs outside of the namespace. Most notably, a process can have a | from its IDs outside of the namespace. Most notably, a process can have a | ||
nonzero user ID outside a namespace while at the same time having a user ID of | nonzero user ID outside a namespace while at the same time having a user ID of | ||
Line 389: | Line 393: | ||
Similar to the previous security feature,, per-user /tmp protect users and the system from mistakes in | Similar to the previous security feature,, per-user /tmp protect users and the system from mistakes in | ||
/tmp handling, by having a private /tmp for each users. This is transparent for them, and each directory is separated. | /tmp handling, by having a private /tmp for each users. This is transparent for them, and each directory is separated. | ||
This feature is implemented using pam_namespace.so. | This feature is implemented using ''pam_namespace.so''. | ||
Line 546: | Line 550: | ||
RELRO stands for RELocation Read-Only, it is a mitigation technique to harden | RELRO stands for RELocation Read-Only, it is a mitigation technique to harden | ||
data sections of an ELF/process. It is used to move commonly exploited structures | data sections of an ELF/process. It is used to move commonly exploited structures | ||
in ELF binary to a | in ELF binary to a read-only location.It Hardens ELF programs against loader memory | ||
area overwrites by having the loader mark any areas of the relocation table as read-only | area overwrites by having the loader mark any areas of the relocation table as read-only | ||
for any symbols resolved at load-time ("read-only relocations"). This reduces the area of | for any symbols resolved at load-time ("read-only relocations"). This reduces the area of | ||
Line 559: | Line 563: | ||
- ELF sections are reordered, so that ELF internal data sections (.got, .dtors, etc) | - ELF sections are reordered, so that ELF internal data sections (.got, .dtors, etc) | ||
precede the program's data sections (.data and .bss) | |||
- non-PLT GOT is read-only | - non-PLT GOT is read-only | ||
Line 576: | Line 580: | ||
control over program execution flow. | control over program execution flow. | ||
So the question is what | So the question is what are GOT and PLT? | ||
GOT (Global Offset Table) redirects position independent address calculations to an absolute | GOT (Global Offset Table) redirects position independent address calculations to an absolute | ||
location and is located in .got section of an ELF executable or shared object. It has the final | location and is located in .got section of an ELF executable or shared object. It has the final | ||
location of a function calls symbol, used with dynamically linked code. By default GOT is created | location of a function calls symbol, used with dynamically linked code. By default GOT is created | ||
dynamically while program is running. The first time | dynamically while program is running. The first time function is called GOT contains pointer back | ||
to PLT (Procedure Linkage Table), where linker is called to find actual location of the function. | to PLT (Procedure Linkage Table), where linker is called to find actual location of the function. | ||
The location found is written to GOT, Second time whenever the function is called GOT already | The location found is written to GOT, Second time whenever the function is called GOT already | ||
Line 611: | Line 615: | ||
=== Built with BIND_NOW === | === Built with BIND_NOW === | ||
Marks ELF programs to resolve all dynamic symbols at start-up (instead of on-demand, also known as "immediate binding") so that the GOT can be made entirely read-only (when combined with RELRO above). | Marks ELF programs to resolve all dynamic symbols at start-up (instead of | ||
on-demand, also known as "immediate binding") so that the GOT can be made | |||
entirely read-only (when combined with RELRO above). | |||
Line 697: | Line 703: | ||
There is no modern user of ''/dev/kmem'' any more beyond | There is no modern user of ''/dev/kmem'' any more beyond | ||
attackers using it to load kernel rootkits. | attackers using it to load kernel rootkits. | ||
[http://lkml.org/lkml/2008/2/10/328 CONFIG_DEVKMEM] is set to | [http://lkml.org/lkml/2008/2/10/328 CONFIG_DEVKMEM] is set to ''n''. | ||
Line 779: | Line 785: | ||
See [http://danwalsh.livejournal.com/58647.html Forward Secure Sealing (FSS) article] for | See [http://danwalsh.livejournal.com/58647.html Forward Secure Sealing (FSS) article] for | ||
more information. | |||
=== Overflow checking in new operator === | |||
GCC performs overflow checking in operator new[], and all C++ code is compiled with this hardening feature. | |||
See [https://securityblog.redhat.com/2012/10/31/array-allocation-in-cxx/ Array allocation in C++ article] for | |||
more information. | more information. | ||
= Additional Documentation = | = Additional Documentation = | ||
* Coordination with Ubuntu: https://wiki.ubuntu.com/Security/Features | * Coordination with Ubuntu: https://wiki.ubuntu.com/Security/Features | ||
* Coordination with Debian: http://wiki.debian.org/Hardening | * Coordination with Debian: http://wiki.debian.org/Hardening | ||
* Gentoo's Hardening project: http://www.gentoo.org/proj/en/hardened/hardened-toolchain.xml | * Gentoo's Hardening project: http://www.gentoo.org/proj/en/hardened/hardened-toolchain.xml |
Revision as of 16:29, 9 February 2014
By Default |
Available |
Unimplemented |
Security Features | RHEL 3 | RHEL 4 | RHEL 5 | RHEL 6 | Fedora 19 | Fedora 20 | Rawhide |
Configurable Firewall | iptables | iptables | iptables | iptables | firewalld | firewalld | firewalld |
Signed updates | yum | yum | yum | yum | yum / dnf | yum / dnf | yum / dnf |
SELinux | N | Y | Y | Y | Y | Y | Y |
SELinux targeted policy | N | Y | Y | Y | Y | Y | Y |
SELinux Executable Memory Protection | N | N | Y | Y | Y | Y | Y |
Password hashing | md5crypt | md5crypt | md5crypt | sha512crypt | sha512crypt | sha512crypt | sha512crypt |
Filesystem Capabilities | -- | kernel | kernel | kernel | kernel | kernel | kernel |
SELinux user confinement | N | N | Y | Y | Y | Y | Y |
SELinux XACE | N | N | N | Y | Y | Y | Y |
SELinux sandbox | N | N | N | Y | Y | Y | Y |
PR_SET_SECCOMP | -- | -- | -- | -- | kernel | kernel | kernel |
SELinux Deny Ptrace | N | N | N | N | kernel & sysctl | kernel & sysctl | kernel & sysctl |
SELinux restricted module loading | N | N | ? | ? | Y | Y | Y |
User namespaces | N | N | N | N | N | N | Y |
/tmp namespace for systemd | N | N | N | N | Y | Y | Y |
per-user temp folder | -- | -- | -- | -- | -- | -- | -- |
Encrypted LVM | ? | ? | Y | Standard Installer | Standard Installer | Standard Installer | Standard Installer |
eCryptfs | N | N | Y | Y | Optional Package | Optional Package | Optional Package |
Non-Executable Memory (NX) | Y (since 9/2004) | Y | Y | Y | Y | Y | Y |
Built as PIE | package list (since 9/2004) | package list | package list | package list | package list | package list | package list |
Pointer Obfuscation | N | N | Y | Y | glibc | glibc | glibc |
Heap Protector | N | glibc | glibc | glibc | glibc | glibc | glibc |
Built with Fortify Source | N | Y | Y | Y | Y | Y | Y |
Stack Protector | N | N | Y | Y | Y | Y | Y |
Stack ASLR | Y (since 9/2004) | kernel | kernel | kernel | kernel | kernel | kernel |
Libs/mmap ASLR | kernel (since 9/2004) | kernel | kernel | kernel | kernel | kernel | kernel |
Exec ASLR | (since 9/2004) | Y | y | Y | Y | Y | Y |
brk ASLR | N | N | ? | Y | Y | Y | Y |
VDSO ASLR | no vDSO | kernel | kernel | kernel | kernel | kernel | kernel |
Built with RELRO | -- | -- | -- | -- | gcc patch | gcc patch | gcc patch |
Built with BIND_NOW | N | ? | package list | package list | package list | package list | package list |
/proc/$pid/maps protection | -- | -- | -- | -- | kernel | kernel | kernel |
Symlink restrictions | N | N | N | N | kernel | kernel | kernel |
Hardlink restrictions | N | N | N | N | kernel | kernel | kernel |
ptrace scope | -- | -- | -- | -- | kernel | kernel | kernel |
0-address protection | Y (since 11/2009) | Y (since 9/2009) | Y (since 5/2008) | Y | Y | Y | Y |
Block module loading | Y | Y | Y | Y | Y | Y | Y |
/dev/mem protection | N | Y | Y | Y | Y | Y | Y |
/dev/kmem disabled | N | Y | Y | Y | Y | Y | Y |
Module RO/NX | -- | -- | -- | -- | kernel | kernel | kernel |
Kernel Address Display Restriction | -- | -- | -- | -- | kernel | kernel | kernel |
Blacklist Rare Protocols | Y | Y | Y | Y | Y | Y | Y |
Write-protect kernel .rodata sections | N | N | N | Y | Y | Y | Y |
Kernel Stack Protector | N | N | N | Y | Y | Y | Y |
sVirt labelling | N | N | N | Y | Y | Y | Y |
SYN cookies | ? | kernel | kernel | kernel | kernel | kernel | kernel |
Syscall Filtering | N | N | N | ? | Y | Y | Y |
Secure Boot Support | N | N | N | N | Y | Y | Y |
Tamper Resistant Logs | N | N | N | N | Y | Y | Y |
Overflow checking in new operator | N | N | N | N | Y | Y | Y |
Features
Configuration
Configurable Firewall
firewalld provides a dynamically managed firewall with support for network/firewall zones to define the trust level of network. The former firewall model with system-config-firewall/lokkit was static and every change required a complete firewall restart. The firewall daemon on the other hand manages the firewall dynamically and applies changes without restarting the whole firewall. See FirewallD and system-config-firewall for more information.
Signed updates
Each stable RPM package that is published by Fedora Project is signed with a GPG signature. By default, yum and the graphical update tools will verify these signatures and refuse to install any packages that are not signed or have bad signatures. You should always verify the signature of a package before you install it. These signatures ensure that the packages you install are what was produced by the Fedora Project and have not been altered (accidentally or maliciously) by any mirror or website that is providing the packages. See this page for more information. [MOVE] We use a number of GPG keys to sign our software packages. The necessary public keys are included in the relevant products and are used to automatically verify software updates. See this page for more information.
SELinux
SELinux is an inode-based MAC. See this page and this page for more information.
SELinux targeted policy
SELinux enabled with targeted policy by default. See discussion of policies page and this page for more information.
SELinux Executable Memory Protection
SELinux restricts certain memory protection operation if the appropriate boolean values enable these checks. See this page for more information.
Password hashing
The system password used for logging into Fedora is stored in /etc/shadow. Very old style password hashes were based on DES and visible in /etc/passwd. Modern Linux has long since moved to /etc/shadow, and for some time now has used salted MD5-based hashes for password verification (crypt id 1). Since MD5 is considered "broken" for some uses and as computational power available to perform brute-forcing of MD5 increases, modern Fedora versions have proactively moved to using salted SHA-512 based password hashes (crypt id 6), which are orders of magnitude more difficult to brute-force. See the crypt(3) manpage for additional details.
Subsystems
Filesystem Capabilities
The need for setuid applications can be reduced via the application of filesystem capabilities using the xattrs available to most modern filesystems. This reduces the possible misuse of vulnerable setuid applications. The kernel provides the support and the user-space tools are avaiable in the standard repositories.
Capabilities are defined in /usr/include/linux/capability.h
Linux Capability Version 1 "_LINUX_CAPABILITY_U32S_1" defined as 1 indicates kernel has 32 or less capabilities
Linux Capability Version 2 constant "_LINUX_CAPABILITY_U32S_2" defined as 2 indicated kernel has more than 32 capabilities,
Linux Capability Version 3
"_LINUX_CAPABILITY_U32S_2" is deprecated by "_LINUX_CAPABILITY_U32S_3"
32 bit integer is in /proc/sys/kernel/cap_last_cap which defines the current capability sets Every linux process has sets of bitmaps
typedef struct __user_cap_data_struct {
__u32 effective;
__u32 permitted;
__u32 inheritable;
} *cap_user_data_t;
each capability is implemented as a bit in each of these bitmaps which is either set or unset.
1. effective (E) Effective capability set indicates which capabilities are effective, when some privelage operation is done operating system checks for bit in effective set of the processes rather than effective uid.
2. permitted (P) Indicates which capabilities process can use. Process migh have capabilities set in permitted set but not in the effective set, that would mean that particualar capability is disabled for the process Process can set capability in effective set only if it is available in permitted set.
This combinations of effective and permitted bits allow to enable , disable and drop privelages
3. inheritable (I) Inheritable capability set indicates which capabilities are inheritable by the process which is going to be executed by the current process.
If P1 has X capabilities , then the process P1' which is ran or forked by P1 for example using exec(), how many capabilities out of X can be inherited by P1' is decided by inheritable capabilities set.
The need for setuid applications can be reduced via the application of filesystem capabilities using the xattrs available to most modern filesystems. This reduces the possible misuse of vulnerable setuid applications. The kernel provides the support and the user-space tools are available in the standard repositories.
Programmes have been vulnerable to set-UID, there is no need for having root privileges every time for a process to run, it is logical to provide to minimum set of privileges to programme that can enable the programme to run effectively. With the normal set-UID approach programmes would run more than the privileges required, increasing the risk of Privilege Escalation. Enabling Capabilities to programme has been started since kernel 2.6.24 known as file capability implemented in fs/exec.c in Kernel itself.
Common capabilities are implemented in security/commoncap.c
Implementation in Red Hat Enterprise Linux
RELEASE | KERNEL | CAPABILITY |
RHEL 2 | 2.4.9-e.X | N |
RHEL 3 | 2.4.21-X | N |
RHEL 4 | 2.6.9-X | Y |
RHEL 5 | 2.6.18-X | Y |
RHEL 6 | 2.6.32-X | Y |
Modifying Filesystem Capabilities
There is no specific system call provided by the linux to modify filesystem capabilities. But as its implemented as inode getxattr() , fsetxattr system calls can be used.
Here "$" means normal user and "#" means root user. Let's take 'ping' as working example to show how capabilities work.
$ mkdir CapabilityTest
$ cd CapabilityTest
$ cp which ping
.
$ ./ping -q -c 1 127.0.0.1 ping: icmp open socket: Operation not permitted
# ./ping -q -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.213/0.213/0.213/0.000 ms
# setcap cap_net_raw=ep ./ping # getcap ./ping ./ping = cap_net_raw+ep $ ./ping -q -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.170/0.170/0.170/0.000 ms
from administrators perspective effective bit has to be disabled , so logical way of doing this will be
# setcap cap_net_raw=p ./ping # getcap ./ping ./ping = cap_net_raw+p
$ ./ping -q -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.170/0.170/0.170/0.000 ms
from that it can be concluded that, ping requires more privileges then a normal user for specially crafted network packets, so while running with 'root' user it works as 'root' has all effective capabilities. In the Linux Kernel there is a check which sees if application is capable, which means to run it should have effective capability for CAP_NET_RAW.
Using set-UID root makes 'ping' over privileged, if buffer overflow is detected then attacker could do local privilege escalation giving back shell.
Mandatory Access Control (MAC)
Mandatory Access Controls are handled via the kernel LSM hooks.
SELinux user confinement
Support for SELinux to confine users access on a system. See this page for more information.
SELinux XACE
Support for SELinux X Access Control Extension (XACE). See this page for more information.
SELinux sandbox
Support for SELinux to test untrusted content via a sandbox. See this page and this page for more information.
PR_SET_SECCOMP
Setting SECCOMP for a process is meant to confine it to a small subsystem of system calls. The systemd init daemon supports the seccomp filter mechanism found in the 3.5 kernel. The end result is that processes can be easily configured to be run in a sandboxed environment. See this article for more information.
SELinux Deny Ptrace
A boolean variable to allow SELinux to turn off all processes ability to ptrace other process. See this page and this for more information.
SELinux restricted module loading
Support for SELinux to restrict the loading of kernel modules by unprivileged processes in confined domains was implemented in this commit.
User namespaces
User namespaces allow per-namespace mappings of user and group IDs. This means that a process' user and group IDs inside a user namespace can be different from its IDs outside of the namespace. Most notably, a process can have a nonzero user ID outside a namespace while at the same time having a user ID of zero inside the namespace; in other words, the process is unprivileged for operations outside the user namespace but has root privileges inside the namespace. See this page and this page for more information. See this bug to track this feature.
/tmp namespace for systemd
Run some services started by systemd with a private /tmp directory. This would mitigate the chance of a service making a mistake with how it handles its /tmp data allowing a user on the system to get a privilege escalation, since users would not have access to the services /tmp directory.
See this page for more information.
per-user temp folder
Similar to the previous security feature,, per-user /tmp protect users and the system from mistakes in /tmp handling, by having a private /tmp for each users. This is transparent for them, and each directory is separated. This feature is implemented using pam_namespace.so.
Filesystem encryption
Encrypted LVM
Modern Fedora versions include the ability to install Fedora onto an encrypted LVM, which allows all partitions in the logical volume, including swap, to be encrypted.
eCryptfs
eCryptfs is a cryptographic stacked Linux filesystem. eCryptfs stores cryptographic metadata in the header of each file written, so that encrypted files can be copied between hosts; the file will be decrypted with the proper key in the Linux kernel keyring. See eCryptfs homepage for more details.
Userspace Hardening
Many security features are available through the default compiler flags used to build packages and through the kernel in Fedora.
Non-Executable Memory (NX)
Modern processors support a feature called NX which allows a system to control the execution of various portions of memory. Data memory is flagged as non-executable and program memory is flagged as non-writeable. This helps prevent certain types of buffer overflow exploits from working as expected. Most modern CPUs protect against executing non-executable memory regions (heap, stack, etc). Since not all processors support the NX feature, attempts have been made to support this feature via segment limits. A segment limit will prevent certain portions of memory from being executed. This provides very similar functionality to NX technology. After booting, you can see what NX protection is in effect:
- Hardware-based (via PAE mode):
- [ 0.000000] NX (Execute Disable) protection: active
- Partial Emulation (via segment limits):
- [ 0.000000] Using x86 segment limits to approximate NX protection
For more information, see Security Features page.
Built as PIE
All programs built as Position Independent Executables (PIE) with "-fPIE -pie" can take advantage of the exec ASLR. This protects against "return-to-text" and generally frustrates memory corruption attacks. This requires centralized changes to the compiler options when building the entire archive. PIE has a large (5-10%) performance penalty on architectures with small numbers of general registers (e.g. x86), so it should only be used for a select number of security-critical packages. PIE on x86_64 does not have the same penalties, and will eventually be made the default, but more testing is required. See this paper and this FESCo ticket for more information.
Pointer Obfuscation
Some pointers stored in glibc are obfuscated via PTR_MANGLE/PTR_UNMANGLE macros internally in glibc, preventing libc function pointers from being overwritten during runtime.
Heap Protector
The GNU C Library heap protector (both automatic via ptmalloc and manual) provides corrupted-list/unlink/double-free/overflow protections to the glibc heap memory manager (first introduced in glibc 2.3.4). This stops the ability to perform arbitrary code execution via heap memory overflows that try to corrupt the control structures of the malloc heap memory areas.This protection has evolved over time, adding more and more protections as additional corner-cases were researched. As it currently stands, glibc 2.10 and later appears to successfully resist even these hard-to-hit conditions. See this page for more details.
Built with Fortify Source
Programs built with "-D_FORTIFY_SOURCE=2" (and -O1 or higher), enable several compile-time and run-time protections in glibc:
- expand unbounded calls to "sprintf", "strcpy" into their "n" length-limited cousins when the size of a destination buffer is known (protects against memory overflows).
- stop format string "%n" attacks when the format string is in a writable memory segment.
- require checking various important function return codes and arguments (e.g. system, write, open).
- require explicit file mask when creating new files.
-D_FORTIFY_SOURCE=2 also protects C++ code. See this page for more information.
Stack Protector
gcc's -fstack-protector provides a randomized stack canary that protects against stack overflows, and reduces the chances of arbitrary code execution via controlling return address destinations. Enabled at compile-time. The routines used for stack checking are actually part of glibc, but gcc is patched to enable linking against those routines by default. See this page for more information.
Address Space Layout Randomisation (ASLR)
ASLR is implemented by the kernel and the ELF loader by randomising the location of memory allocations (stack, heap, shared libraries, etc). This makes memory addresses harder to predict when an attacker is attempting a memory-corruption exploit. ASLR is controlled system-wide by the value of /proc/sys/kernel/randomize_va_space. See this article and this article for more information. ASLR is now enabled for all packages by default in Rawhide.
Stack ASLR
Each execution of a program results in a different stack memory space layout. This makes it harder to locate in memory where to attack or deliver an executable attack payload. This feature has been available in the mainline kernel since 2.6.15.
Libs/mmap ASLR
Each execution of a program results in a different mmap memory space layout. This causes the dynamically loaded libraries to get loaded into different locations each time. This makes it harder to locate in memory where to jump to for "return to libc" to similar attacks. This was available in the mainline kernel since 2.6.15.
Exec ASLR
Each execution of a program that has been built with "-fPIE -pie" will get loaded into a different memory location. This makes it harder to locate in memory where to attack or jump to when performing memory-corruption-based attacks. This was available in the mainline kernel since 2.6.25.
brk ASLR
Similar to exec ASLR, brk ASLR adjusts the memory locations relative between the exec memory area and the brk memory area (for small mallocs). The randomization of brk offset from exec memory was added in 2.6.22.
VDSO ASLR
Each execution of a program results in a random vdso location. This has existed in the mainline kernel since 2.6.18 (x86, PPC) and 2.6.22 (x86_64). People needing ancient pre-libc6 static high vdso mappings can use "vdso=2" on the kernel boot command line to gain COMPAT_VDSO again. See this article for more information.
Built with RELRO
RELRO stands for RELocation Read-Only, it is a mitigation technique to harden data sections of an ELF/process. It is used to move commonly exploited structures in ELF binary to a read-only location.It Hardens ELF programs against loader memory area overwrites by having the loader mark any areas of the relocation table as read-only for any symbols resolved at load-time ("read-only relocations"). This reduces the area of possible GOT-overwrite-style memory corruption attacks, specially the GOT is made read-only after relocation by the dynamic linker.
RELRO can be classified into:
Partial RELRO
- Compilation: gcc -Wl,-z,relro
- ELF sections are reordered, so that ELF internal data sections (.got, .dtors, etc) precede the program's data sections (.data and .bss)
- non-PLT GOT is read-only
- GOT is writable
Full RELRO
- compilation: gcc -Wl,-z,relro,-z,now
- Supports all the features of partial RELRO
- In addition , GOT is also remapped as read-only
Only Full RELRO can protect from exploiting technique of overwriting GOT entry to get control over program execution flow.
So the question is what are GOT and PLT?
GOT (Global Offset Table) redirects position independent address calculations to an absolute location and is located in .got section of an ELF executable or shared object. It has the final location of a function calls symbol, used with dynamically linked code. By default GOT is created dynamically while program is running. The first time function is called GOT contains pointer back to PLT (Procedure Linkage Table), where linker is called to find actual location of the function. The location found is written to GOT, Second time whenever the function is called GOT already knows location of the function known as lazy binding.
PLT (Procedure Linker Table) works with GOT to reference and relocate functions. PLT reference will cause a jmp into the GOT and find the location of the called function. On the first call there wont be no entry in GOT, so PLT will hand over the request to the rtld for resolving the function's absolute location, after this GOT will be updated for future references.
Few Constraints about PLT and GOT
1. PLT will always contain code that is called by program directly,so it will be allocated at a known offset from the .text segment.
2. GOT contains data used by different parts of the program directly,so it will be at a static address in the memory.
3. As GOT is "lazy binded",so it needs to be writable
In case of a bss or data overflow bug both partial and full RELRO can protect the ELF internal data sections from being overwritten. With full RELRO a working mitigation technique to successfully prevent the modification of GOT entries is available.Only one reason why full RELRO is not widely used is that the startup of processes is slowed down as the linker has to perform all relocations at startup time.
In short, RELRO hardens ELF programs against loader memory area overwrites by having the loader mark any areas of the relocation table as read-only for any symbols resolved at load-time ("read-only relocations"). This reduces the area of possible GOT-overwrite-style memory corruption attacks.
Built with BIND_NOW
Marks ELF programs to resolve all dynamic symbols at start-up (instead of on-demand, also known as "immediate binding") so that the GOT can be made entirely read-only (when combined with RELRO above).
/proc/$pid/maps protection
With ASLR, a process's memory space layout suddenly becomes valuable to attackers. The "maps" file is made read-only except to the process itself or the owner of the process. Went into mainline kernel with sysctl toggle in 2.6.22. The toggle was made non-optional in 2.6.27, forcing the privacy to be enabled regardless of sysctl settings (this is a good thing).
Symlink restrictions
A long-standing class of security issues is the symlink-based ToCToU race, most commonly seen in world-writable directories like /tmp/. The common method of exploitation of this flaw is crossing privilege boundaries when following a given symlink (i.e. a root user follows a symlink belonging to another user).
In modern Fedora version, symlinks in world-writable sticky directories (e.g. /tmp) cannot be followed if the follower and directory owner do not match the symlink owner. The behavior is controllable through the /proc/sys/kernel/yama/protected_sticky_symlinks sysctl.
Hardlink restrictions
Hardlinks can be abused in a similar fashion to symlinks above, but they are not limited to world-writable directories. If /etc/ and /home/ are on the same partition, a regular user can create a hardlink to /etc/shadow in their home directory. While it retains the original owner and permissions, it is possible for privileged programs that are otherwise symlink-safe to mistakenly access the file through its hardlink. Additionally, a very minor untraceable quota-bypassing local denial of service is possible by an attacker exhausting disk space by filling a world-writable directory with hardlinks.
In modern Fedora versions, hardlinks cannot be created to files that the user would be unable to read and write originally, or are otherwise sensitive.
ptrace scope
A troubling weakness of the Linux process interfaces is that a single user is able to examine the memory and running state of any of their processes. For example, if one application was compromised, it would be possible for an attacker to attach to other running processes (e.g. SSH sessions, GPG agent, etc) to extract additional credentials and continue to immediately expand the scope of their attack without resorting to user-assisted phishing or trojans.
Kernel Hardening
The kernel itself has protections enabled to make it more difficult to become compromised.
0-address protection
Since the kernel and userspace share virtual memory addresses, the "NULL" memory space needs to be protected so that userspace mmap'd memory cannot start at address 0, stopping "NULL dereference" kernel attacks. This is possible with 2.6.22 kernels, and was implemented with the "mmap_min_addr" sysctl setting. See this article for more information.
Block module loading
It is possbile to remove CAP_SYS_MODULES from the system-wide capability bounding set , which would stop any new kernel modules from being loaded. This was another layer of protection to stop kernel rootkits from being installed. This feature to block module loading can be enabled setting 1 in /proc/sys/kernel/modules_disabled.
/dev/mem protection
Some applications (Xorg) need direct access to the physical memory from user-space. The special file /dev/mem exists to provide this access. In the past, it was possible to view and change kernel memory from this file if an attacker had root access. See this page and this page for details.
/dev/kmem disabled
There is no modern user of /dev/kmem any more beyond attackers using it to load kernel rootkits. CONFIG_DEVKMEM is set to n.
Module RO/NX
This feature extends CONFIG_DEBUG_RODATA to include similar restrictions for loaded modules in the kernel. This can help resist future kernel exploits that depend on various memory regions in loaded modules. Enabled via the CONFIG_DEBUG_MODULE_RONX option.
Kernel Address Display Restriction
When attackers try to develop run anywhere exploits for kernel vulnerabilities, they frequently need to know the location of internal kernel structures. By treating kernel addresses as sensitive information, those locations are not visible to regular local users. /proc/sys/kernel/kptr_restrict is set to 1 to block the reporting of known kernel address leaks. Additionally, various files and directories were made readable only by the root user: /boot/vmlinuz, /boot/System.map, /sys/kernel/debug/, /proc/slabinfo.
Blacklist Rare Protocols
Normally the kernel allows all network protocols to be autoloaded on demand. Many of these protocols are old, rare, or generally of little use to the average Fedora user and may contain undiscovered exploitable vulnerabilities. These include: ax25, netrom, x25, rose, decnet, econet, rds, and af_802154. If any of the protocols are needed, they can speficially loaded via modprobe, or the /etc/modprobe.d/blacklist-rare-network.conf file can be updated to remove the blacklist entry. A FESCo proposal to do this for Fedora is in progress.
Write-protect kernel .rodata sections
Enabled write-protection for kernel read-only data structures by default. See this commit for details. This makes sure that certain kernel data sections are marked to block modification. This helps protect against some classes of kernel rootkits. Enabled via the CONFIG_DEBUG_RODATA option.
Kernel Stack Protector
Similar to the stack protector used for ELF programs in userspace, the kernel can protect its internal stacks as well. This feature is enabled via the CONFIG_CC_STACKPROTECTOR option.
See commits 1, 2 and 3 for more details.
sVirt labelling
Support for sVirt labelling to provide security over guest instances. See this page for more information.
SYN cookies
When a system is overwhelmed by new network connections, SYN cookie use is activated, which helps mitigate a SYN-flood attack. This feature can be controlled by /proc/sys/net/ipv4/tcp_syncookies file.
Syscall Filtering
Programs can filter out the availability of kernel syscalls by using the seccomp_filter interface. This is done in containers or sandboxes that want to further limit the exposure to kernel interfaces when potentially running untrusted software.
Secure Boot Support
"Secure Boot" describes a UEFI feature by which malware is prevented from inserting itself into the boot process before the operating system loads. See Fedora + UEFI Secure Boot article for more details.
Tamper Resistant Logs
See Forward Secure Sealing (FSS) article for more information.
Overflow checking in new operator
GCC performs overflow checking in operator new[], and all C++ code is compiled with this hardening feature. See Array allocation in C++ article for more information.
Additional Documentation
- Coordination with Ubuntu: https://wiki.ubuntu.com/Security/Features
- Coordination with Debian: http://wiki.debian.org/Hardening
- Gentoo's Hardening project: http://www.gentoo.org/proj/en/hardened/hardened-toolchain.xml