File:  [NetBSD Developer Wiki] / wikisrc / pkgsrc / hardening.mdwn
Revision 1.39: download - view: text, annotated - select for diffs
Sun Jan 6 14:58:39 2019 UTC (3 years, 4 months ago) by leot
Branches: MAIN
CVS tags: HEAD
Adjust enabled by default title.

All the features documented that are enabled by defaut (were and)
are enabled by default in both latest stable and HEAD, avoid to
distinguish them.

    1: [[!meta title="Hardening pkgsrc"]]
    2: 
    3: A number of mechanisms are available in
    4: [pkgsrc](https://www.pkgsrc.org/) to improve the security of the
    5: resulting system. This page describes the mechanisms, and gives hints
    6: about detecting and fixing problems.
    7: 
    8: # Mechanisms
    9: 
   10: Mechanisms can be enabled individually in `mk.conf`, and are
   11: individually described below. They are sorted by whether they are
   12: enabled by default, and then by their ordering in `mk/defaults/mk.conf`.
   13: 
   14: Typically, a feature will cause some programs to fail to build or work
   15: when first enabled. This can be due to latent problems in the
   16: program, and can be due to other reasons. After enough testing to
   17: have confidence that user problems will be quite rare, individual
   18: mechanisms will be enabled by default.
   19: 
   20: For each mechanism, see the Caveats section below for an explanation
   21: of what might go wrong at compile time and at run time, and how to
   22: notice and address these problems.
   23: 
   24: ## Enabled by default
   25: 
   26: ### PKGSRC_USE_FORTIFY
   27: 
   28: This allows substitute wrappers to be used for some commonly used
   29: library functions that do not have built-in bounds checking - but
   30: could in some cases.
   31: 
   32: TODO: Explain FORTIFY_SOURCE 1 vs 2, and which is used. Give a link
   33: to a good explanation of the technique. Explain if this is gcc specific.
   34: 
   35: It has been enabled by default since pkgsrc-2017Q3.
   36: 
   37: ### PKGSRC_USE_SSP
   38: 
   39: This enables a stack-smashing protection mitigation. It is done by adding a
   40: guard variable to functions with vulnerable objects. The guards are initialized
   41: when a function is entered and then checked when the function exits. The guard
   42: check will fail and the program forcibly exited if the variable was modified in
   43: the meantime. This can happen in case of buffer overflows or memory corruption,
   44: and therefore exposing these bugs.
   45: 
   46: Different mitigation levels are available:
   47: 
   48: * the default ("yes"), which will only protect functions considered vulnerable
   49:   by the compiler;
   50: * "all", which will protect every function;
   51: * "strong", which will apply a better balance between the two settings above.
   52: 
   53: This mitigation is supported by both GCC and clang. It may be supported in
   54: additional compilers, possibly under a different name. It is particularly useful
   55: for unsafe programming languages, such as C/C++.
   56: 
   57: It is enabled by default where known supported since pkgsrc-2017Q3.
   58: 
   59: More details can be found here:
   60: 
   61: * <https://en.wikipedia.org/wiki/Buffer_overflow_protection>
   62: 
   63: ## Not enabled by default
   64: 
   65: ### PKGSRC_MKPIE
   66: 
   67: This requests the creation of PIE (Position Independent Executables) for all
   68: executables. The PIE mechanism is normally used for shared libraries, so that
   69: they can be loaded at differing addresses at runtime. PIE itself does not have
   70: useful security properties; however, it is necessary to fully leverage some,
   71: such as ASLR.  Some operating systems support Address Space Layout Randomization
   72: (ASLR), which causes different addresses to be used each time a program is run.
   73: This makes it more difficult for an attacker to guess addresses and thus makes
   74: exploits harder to construct. With PIE, ASLR can really be applied to the entire
   75: program, instead of the stack and heap only.
   76: 
   77: PIE executables will only be built for toolchains that are known to support PIE.
   78: Currently, this means NetBSD on amd64 and i386.
   79: 
   80: ### PKGSRC_MKREPRO
   81: 
   82: With this option, pkgsrc will try to build packages reproducibly. This allows
   83: packages built from the same tree and with the same options, to produce
   84: identical results bit by bit. This option should be combined with ASLR and
   85: `PKGSRC_MKPIE` to avoid predictable address offsets for attackers attempting to
   86: exploit security vulnerabilities.
   87: 
   88: More details can be found here:
   89: 
   90: * <https://reproducible-builds.org/>
   91: 
   92: ### PKGSRC_USE_RELRO
   93: 
   94: This also makes the exploitation of some security vulnerabilities more
   95: difficult in some cases.
   96: 
   97: Two different mitigation levels are available:
   98: 
   99: * partial: the ELF sections are reordered so that internal data sections
  100:   precede the program's own data sections, and non-PLT GOT is read-only;
  101: * full: in addition to partial RELRO, every relocation is performed immediately
  102:   when starting the program (with a slight performance impact), allowing the
  103:   entire GOT to be read-only.
  104: 
  105: This is currently supported by GCC. Many software distributions now enable this
  106: feature by default, at the "partial" level.
  107: 
  108: More details can be found here:
  109: 
  110: * <http://tk-blog.blogspot.co.at/2009/02/relro-not-so-well-known-memory.html>
  111: 
  112: ### PKGSRC_USE_STACK_CHECK
  113: 
  114: This uses `-fstack-check` with GCC for another stack protection mitigation.
  115: 
  116: It asks the compiler to generate code verifying that it does not corrupt the
  117: stack. According to GCC's manual page, this is really only useful for
  118: multi-threaded programs.
  119: 
  120: # Caveats
  121: 
  122: ## Problems with `PKGSRC_MKPIE`
  123: 
  124: ### Recent support for cwrappers
  125: 
  126: `PKGSRC_MKPIE` is only supported by `pkgtools/cwrappers` from the 2017Q3
  127: release on (`USE_CWRAPPERS` in `mk.conf`).
  128: 
  129: ### Packages failing to build
  130: 
  131: A number of packages may fail to build with this option enabled. The failures
  132: are often related to the absence of the `-fPIC` compilation flag when building
  133: libraries or executables (or ideally `-fPIE` in the latter case). This flag is
  134: added to the `CFLAGS` already, but requires the package to actually support it.
  135: 
  136: #### How to fix
  137: 
  138: These instructions are meant as a reference only; they likely need to be adapted
  139: for many packages individually.
  140: 
  141: For packages using `Makefiles`:
  142: 
  143:     MAKE_FLAGS+=	CFLAGS=${CFLAGS:Q}
  144:     MAKE_FLAGS+=	LDFLAGS=${LDFLAGS:Q}
  145: 
  146: For packages using `Imakefiles`:
  147: 
  148:     MAKE_FLAGS+=	CCOPTIONS=${CFLAGS:Q}
  149:     MAKE_FLAGS+=	LOCAL_LDFLAGS=${LDFLAGS:Q}
  150: 
  151: ### Run-time crashes
  152: 
  153: Some programs may fail to run, or crash at random times once built as PIE. Two
  154: scenarios are essentially possible:
  155: 
  156: * actual bug in the program crashing, exposed thanks to ASLR/mprotect;
  157: * bug in the implementation of ASLR/mprotect in the Operating System.
  158: 
  159: ## Problems with `PKGSRC_USE_FORTIFY`
  160: 
  161: ### Packages failing to build
  162: 
  163: This feature makes use of pre-processing directives to look for hardened,
  164: alternative implementations of essential library calls. Some programs may fail
  165: to build as a result; this usually happens for those trying too hard to be
  166: portable, or otherwise abusing definitions in the standard library.
  167: 
  168: This will require a modification to the program, or disabling this feature for
  169: part or all of the build.
  170: 
  171: ### Run-time crashes
  172: 
  173: Just like with `PKGSRC_MKPIE` above, this feature may cause some programs to
  174: crash, usually indicating an actual bug in the program. The fix will typically
  175: involve patching the original program.
  176: 
  177: ### Optimization is required
  178: 
  179: At least in the case of GCC, FORTIFY will only be applied if optimization is
  180: applied while compiling. This means that the CFLAGS should also contain -O, -O2
  181: or another optimization level. This cannot easily be applied globally, as some
  182: packages may require specific optimization levels.
  183: 
  184: ## Problems with `PKGSRC_USE_RELRO`
  185: 
  186: ### Performance impact
  187: 
  188: For better protection, full RELRO requires every symbol to be resolved when the
  189: program starts, rather than simply when required at run-time. This will have
  190: more impact on programs using a lot of symbols, or linked to libraries exposing
  191: a lot of symbols. Therefore, daemons or programs otherwise running in
  192: background are affected only when started. Programs loading plug-ins at
  193: run-time are affected when loading the plug-ins.
  194: 
  195: The impact is not expected to be noticeable on modern hardware, except in some
  196: cases for big programs.
  197: 
  198: ### Run-time crashes
  199: 
  200: Some programs handle plug-ins and dependencies in a way that conflicts with
  201: RELRO: for instance, with an initialization routine listing any other plug-in
  202: required. With full RELRO, the missing symbols are resolved before the
  203: initialization routine can run, and the dynamic loader will not be able to find
  204: them directly and abort as a result. Unfortunately, this is how Xorg loads its
  205: drivers. Partial RELRO can be applied instead in this case.
  206: 
  207: ## Problems with `PKGSRC_USE_SSP`
  208: 
  209: ### Packages failing to build
  210: 
  211: The stack-smashing protection provided by this option does not work for some
  212: programs. The two most common situations in which this happens are:
  213: 
  214: * the program makes use of the `alloca(3)` library call (memory allocator on the
  215:   stack)
  216: * the program allocates variables on the stack, with the size determined at
  217:   run-time.
  218: 
  219: Both cases will require a modification to the program, or disabling this feature
  220: for part or all of the build.
  221: 
  222: ### Run-time crashes
  223: 
  224: Again, this feature may cause some programs to crash, usually indicating an
  225: actual bug in the program. Patching the original program is then required.
  226: 
  227: ### Performance impact
  228: 
  229: The compiler emits extra code when using this feature: a check for buffer
  230: overflows is performed when entering and exiting functions, requiring an extra
  231: variable on the stack. The level of protection can otherwise be adjusted to
  232: affect only those functions considered more sensitive by the compiler (with
  233: `-fstack-protector` instead of `-fstack-protector-all`).
  234: 
  235: The impact is not expected to be noticeable on modern hardware. However,
  236: programs with a hard requirement to run at the fastest possible speed should
  237: avoid using this feature, or using libraries built with this feature.
  238: 
  239: # Auditing the system
  240: 
  241: The illusion of security is worse than having no security at all. This section
  242: lists a number of ways to ensure the security features requested are actually
  243: effective.
  244: 
  245: _These instructions were obtained and tested on a system derived from NetBSD 7
  246: (amd64). YMMV._
  247: 
  248: ## Checking for PIE
  249: 
  250: The ELF executable type in use changes for binaries built as PIE; without:
  251: 
  252:     $ file /path/to/bin/ary
  253:     /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
  254: 
  255: as opposed to the following binary, built as PIE:
  256: 
  257:     $ file /path/to/pie/bin/ary
  258:     /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
  259: 
  260: The latter result is then what is expected.
  261: 
  262: ## Checking for partial RELRO
  263: 
  264: The following command should list a section called `RELRO`:
  265: 
  266:     $ objdump -p /path/to/bin/ary
  267: 
  268:     /path/to/bin/ary:     file format elf64-x86-64
  269: 
  270:     Program Header:
  271:     [...]
  272:        RELRO off    0x0000000000000d78 vaddr 0x0000000000600d78 paddr 0x0000000000600d78 align 2**0
  273: 
  274: This check is now performed automatically if `PKG_DEVELOPER` is set and `RELRO`
  275: is enabled.
  276: 
  277: ## Checking for full RELRO
  278: 
  279: The dynamic loader will apply RELRO immediately when detecting the presence of
  280: the `BIND_NOW` flag:
  281: 
  282:     $ objdump -x /path/to/bin/ary
  283: 
  284:     /path/to/bin/ary:     file format elf64-x86-64
  285: 
  286:     Dynamic Section:
  287:     [...]
  288:       BIND_NOW             0x0000000000000000
  289: 
  290: This has to be combined with partial RELRO (see above) to be fully efficient.
  291: 
  292: ## Checking for SSP
  293: 
  294: Building objects, binaries and libraries with SSP will affect the presence of
  295: additional symbols in the resulting file:
  296: 
  297:     $ nm /path/to/bin/ary
  298:     [...]
  299:                      U __stack_chk_fail
  300:     0000000000600ea0 B __stack_chk_guard
  301: 
  302: This is an indicator that the program was indeed built with support for SSP.
  303: 
  304: This check is now performed automatically (where supported) if `PKG_DEVELOPER`
  305: is set and `SSP` is enabled.

CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb