version 1.31, 2017/11/07 02:22:50
|
version 1.49, 2021/10/02 14:48:27
|
Line 1
|
Line 1
|
[[!meta title="Hardening pkgsrc"]] |
This page has been moved to [the pkgsrc guide](//www.NetBSD.org/docs/pkgsrc/hardening.html). |
|
|
A number of mechanisms are available in |
|
[pkgsrc](https://www.pkgsrc.org/) to improve the security of the |
|
resulting system. This page describes the mechanisms, and gives hints |
|
about detecting and fixing problems. |
|
|
|
# Mechanisms |
|
|
|
Mechanisms can be enabled individually in `mk.conf`, and are |
|
individually described below. They are sorted by whether they are |
|
enabled by default, and then by their ordering in `mk/defaults/mk.conf`. |
|
|
|
Typically, a feature will cause some programs to fail to build or work |
|
when first enabled. This can be due to latent problems in the |
|
program, and can be due to other reasons. After enough testing to |
|
have confidence that user problems will be quite rare, individual |
|
mechanisms will be enabled by default. |
|
|
|
For each mechanism, see the Caveats section below for an explanation |
|
of what might go wrong at compile time and at run time, and how to |
|
notice and address these problems. |
|
|
|
## Enabled by default in the stable branch |
|
|
|
### PKGSRC_USE_FORTIFY |
|
|
|
This allows substitute wrappers to be used for some commonly used |
|
library functions that do not have built-in bounds checking - but |
|
could in some cases. |
|
|
|
TODO: Explain FORTIFY_SOURCE 1 vs 2, and which is used. Give a link |
|
to a good explanation of the technique. Explain if this is gcc specific. |
|
|
|
It has been enabled by default since pkgsrc-2017Q3. |
|
|
|
### PKGSRC_USE_SSP |
|
|
|
This enables a stack-smashing protection mitigation. It is done by adding a |
|
guard variable to functions with vulnerable objects. The guards are initialized |
|
when a function is entered and then checked when the function exits. The guard |
|
check will fail and the program forcibly exited if the variable was modified in |
|
the meantime. This can happen in case of buffer overflows or memory corruption, |
|
and therefore exposing these bugs. |
|
|
|
Different mitigation levels are available: |
|
* the default ("yes"), which will only protect functions considered vulnerable |
|
by the compiler; |
|
* "all", which will protect every function; |
|
* "strong", which will apply a better balance between the two settings above. |
|
|
|
This mitigation is supported by both GCC and clang. It may be supported in |
|
additional compilers, possibly under a different name. It is particularly useful |
|
for unsafe programming languages, such as C/C++. |
|
|
|
It is enabled by default where known supported since pkgsrc-2017Q3. |
|
|
|
* <https://en.wikipedia.org/wiki/Buffer_overflow_protection> |
|
|
|
## Enabled by default in pkgsrc HEAD |
|
|
|
## Not enabled by default |
|
|
|
### PKGSRC_MKPIE |
|
|
|
This requests the the creation of PIE (Position Independent |
|
Executables) for all executables. The PIE mechanism is normally used |
|
for shared libraries so that they can be loaded at differing addresses |
|
at runtime. PIE itself does not have useful security properties. |
|
However, some operating systems support Address Space Layout |
|
Randomization (ASLR), which causes different addresses to be used each |
|
time a program is run. This makes it more difficult for an attacker |
|
to guess addresses and thus makes exploits harder to construct. |
|
|
|
PIE executables will only be built for toolchains that are known to support PIE. |
|
Currently, this means NetBSD on amd64 and i386. |
|
|
|
### PKGSRC_USE_RELRO |
|
|
|
This also makes the exploitation of some security vulnerabilities more |
|
difficult in some cases. |
|
|
|
TODO: Explain gcc vs clang, and whether this has broad support or just |
|
a few platforms. |
|
|
|
TODO: Address "partial" vs "full"; which is this? |
|
|
|
TODO: Give a link to a comprehensive explanation. |
|
|
|
### PKGSRC_USE_STACK_CHECK |
|
|
|
This uses `-fstack-check` with GCC for another stack protection |
|
mitigation. |
|
|
|
# Caveats |
|
|
|
## Problems with `PKGSRC_MKPIE` |
|
|
|
### Recent support for cwrappers |
|
|
|
`PKGSRC_MKPIE` is only supported by `pkgtools/cwrappers` from the 2017Q3 |
|
release on (`USE_CWRAPPERS` in `mk.conf`). |
|
|
|
### Packages failing to build |
|
|
|
A number of packages may fail to build with this option enabled. The failures |
|
are often related to the absence of the `-fPIC` compilation flag when building |
|
libraries or executables (or ideally `-fPIE` in the latter case). This flag is |
|
added to the `CFLAGS` already, but requires the package to actually support it. |
|
|
|
#### How to fix |
|
|
|
These instructions are meant as a reference only; they likely need to be adapted |
|
for many packages individually. |
|
|
|
For packages using `Makefiles`: |
|
|
|
MAKE_FLAGS+= CFLAGS=${CFLAGS:Q} |
|
MAKE_FLAGS+= LDFLAGS=${LDFLAGS:Q} |
|
|
|
For packages using `Imakefiles`: |
|
|
|
MAKE_FLAGS+= CCOPTIONS=${CFLAGS:Q} |
|
MAKE_FLAGS+= LOCAL_LDFLAGS=${LDFLAGS:Q} |
|
|
|
### Run-time crashes |
|
|
|
Some programs may fail to run, or crash at random times once built as PIE. Two |
|
scenarios are essentially possible: |
|
|
|
* actual bug in the program crashing, exposed thanks to ASLR/mprotect; |
|
* bug in the implementation of ASLR/mprotect in the Operating System. |
|
|
|
## Problems with `PKGSRC_USE_FORTIFY` |
|
|
|
### Packages failing to build |
|
|
|
This feature makes use of pre-processing directives to look for hardened, |
|
alternative implementations of essential library calls. Some programs may fail |
|
to build as a result; this usually happens for those trying too hard to be |
|
portable, or otherwise abusing definitions in the standard library. |
|
|
|
This will require a modification to the program, or disabling this feature for |
|
part or all of the build. |
|
|
|
### Run-time crashes |
|
|
|
Just like with `PKGSRC_MKPIE` above, this feature may cause some programs to |
|
crash, usually indicating an actual bug in the program. The fix will typically |
|
involve patching the original program. |
|
|
|
### Optimization is required |
|
|
|
At least in the case of GCC, FORTIFY will only be applied if optimization is |
|
applied while compiling. This means that the CFLAGS should also contain -O, -O2 |
|
or another optimization level. This cannot easily be applied globally, as some |
|
packages may require specific optimization levels. |
|
|
|
## Problems with `PKGSRC_USE_RELRO` |
|
|
|
### Performance impact |
|
|
|
For better protection, full RELRO requires every symbol to be resolved when the |
|
program starts, rather than simply when required at run-time. This will have |
|
more impact on programs using a lot of symbols, or linked to libraries exposing |
|
a lot of symbols. Therefore, daemons or programs otherwise running in |
|
background are affected only when started. Programs loading plug-ins at |
|
run-time are affected when loading the plug-ins. |
|
|
|
The impact is not expected to be noticeable on modern hardware, except in some |
|
cases for big programs. |
|
|
|
### Run-time crashes |
|
|
|
Some programs handle plug-ins and dependencies in a way that conflicts with |
|
RELRO: for instance, with an initialization routine listing any other plug-in |
|
required. With full RELRO, the missing symbols are resolved before the |
|
initialization routine can run, and the dynamic loader will not be able to find |
|
them directly and abort as a result. Unfortunately, this is how Xorg loads its |
|
drivers. Partial RELRO can be applied instead in this case. |
|
|
|
## Problems with `PKGSRC_USE_SSP` |
|
|
|
### Packages failing to build |
|
|
|
The stack-smashing protection provided by this option does not work for some |
|
programs. The two most common situations in which this happens are: |
|
|
|
* the program makes use of the `alloca(3)` library call (memory allocator on the |
|
stack) |
|
* the program allocates variables on the stack, with the size determined at |
|
run-time. |
|
|
|
Both cases will require a modification to the program, or disabling this feature |
|
for part or all of the build. |
|
|
|
### Run-time crashes |
|
|
|
Again, this feature may cause some programs to crash, usually indicating an |
|
actual bug in the program. Patching the original program is then required. |
|
|
|
### Performance impact |
|
|
|
The compiler emits extra code when using this feature: a check for buffer |
|
overflows is performed when entering and exiting functions, requiring an extra |
|
variable on the stack. The level of protection can otherwise be adjusted to |
|
affect only those functions considered more sensitive by the compiler (with |
|
`-fstack-protector` instead of `-fstack-protector-all`). |
|
|
|
The impact is not expected to be noticeable on modern hardware. However, |
|
programs with a hard requirement to run at the fastest possible speed should |
|
avoid using this feature, or using libraries built with this feature. |
|
|
|
# Auditing the system |
|
|
|
The illusion of security is worse than having no security at all. This section |
|
lists a number of ways to ensure the security features requested are actually |
|
effective. |
|
|
|
_These instructions were obtained and tested on a system derived from NetBSD 7 |
|
(amd64). YMMV._ |
|
|
|
## Checking for PIE |
|
|
|
The ELF executable type in use changes for binaries built as PIE; without: |
|
|
|
$ file /path/to/bin/ary |
|
/path/to/bin/ary: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for NetBSD 7.0, not stripped |
|
|
|
as opposed to the following binary, built as PIE: |
|
|
|
$ file /path/to/pie/bin/ary |
|
/path/to/pie/bin/ary: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for NetBSD 7.0, not stripped |
|
|
|
The latter result is then what is expected. |
|
|
|
## Checking for partial RELRO |
|
|
|
The following command should list a section called `RELRO`: |
|
|
|
$ objdump -p /path/to/bin/ary |
|
|
|
/path/to/bin/ary: file format elf64-x86-64 |
|
|
|
Program Header: |
|
[...] |
|
RELRO off 0x0000000000000d78 vaddr 0x0000000000600d78 paddr 0x0000000000600d78 align 2**0 |
|
|
|
This check is now performed automatically if `PKG_DEVELOPER` is set and `RELRO` |
|
is enabled. |
|
|
|
## Checking for full RELRO |
|
|
|
The dynamic loader will apply RELRO immediately when detecting the presence of |
|
the `BIND_NOW` flag: |
|
|
|
$ objdump -x /path/to/bin/ary |
|
|
|
/path/to/bin/ary: file format elf64-x86-64 |
|
|
|
Dynamic Section: |
|
[...] |
|
BIND_NOW 0x0000000000000000 |
|
|
|
This has to be combined with partial RELRO (see above) to be fully efficient. |
|
|
|
## Checking for SSP |
|
|
|
Building objects, binaries and libraries with SSP will affect the presence of |
|
additional symbols in the resulting file: |
|
|
|
$ nm /path/to/bin/ary |
|
[...] |
|
U __stack_chk_fail |
|
0000000000600ea0 B __stack_chk_guard |
|
|
|
This is an indicator that the program was indeed built with support for SSP. |
|
|
|
# References |
|
|
|
* <http://tk-blog.blogspot.co.at/2009/02/relro-not-so-well-known-memory.html> |
|
|
|