File:  [NetBSD Developer Wiki] / wikisrc / pkgsrc / hardening.mdwn
Revision 1.48: download - view: text, annotated - select for diffs
Fri Oct 1 15:48:03 2021 UTC (11 months, 3 weeks ago) by wiki
Branches: MAIN
CVS tags: HEAD
web commit by nia

    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: Two mitigation levels are available:
   33: 
   34: - "weak" only enables checks at compile-time.
   35: - "strong" enables checks at compile-time and runtime.
   36: 
   37: `strong` has been enabled by default since pkgsrc-2017Q3.
   38: 
   39: ### PKGSRC_USE_SSP
   40: 
   41: This enables a stack-smashing protection mitigation. It is done by adding a
   42: guard variable to functions with vulnerable objects. The guards are initialized
   43: when a function is entered and then checked when the function exits. The guard
   44: check will fail and the program forcibly exited if the variable was modified in
   45: the meantime. This can happen in case of buffer overflows or memory corruption,
   46: and therefore exposing these bugs.
   47: 
   48: Different mitigation levels are available:
   49: 
   50: * "yes", which will only protect functions considered vulnerable
   51:   by the compiler;
   52: * "all", which will protect every function;
   53: * "strong", the default, which will apply a better balance between the two settings above.
   54: 
   55: This mitigation is supported by both GCC and clang. It may be supported in
   56: additional compilers, possibly under a different name. It is particularly useful
   57: for unsafe programming languages, such as C/C++.
   58: 
   59: "yes" is enabled by default where known supported since pkgsrc-2017Q3.
   60: "strong" is enabled by default where known supported since pkgsrc-2021Q4.
   61: 
   62: More details can be found here:
   63: 
   64: * <https://en.wikipedia.org/wiki/Buffer_overflow_protection>
   65: 
   66: ### PKGSRC_MKPIE
   67: 
   68: This requests the creation of PIE (Position Independent Executables) for all
   69: executables. The PIE mechanism is normally used for shared libraries, so that
   70: they can be loaded at differing addresses at runtime. PIE itself does not have
   71: useful security properties; however, it is necessary to fully leverage some,
   72: such as ASLR.  Some operating systems support Address Space Layout Randomization
   73: (ASLR), which causes different addresses to be used each time a program is run.
   74: This makes it more difficult for an attacker to guess addresses and thus makes
   75: exploits harder to construct. With PIE, ASLR can really be applied to the entire
   76: program, instead of the stack and heap only.
   77: 
   78: PIE executables will only be built for toolchains that are known to support PIE.
   79: Currently, this means NetBSD on x86, ARM, SPARC64, m68k, and MIPS.
   80: 
   81: PKGSRC_MKPIE was enabled by default after the pkgsrc-2021Q3 branch.
   82: 
   83: 
   84: ### PKGSRC_USE_RELRO
   85: 
   86: This also makes the exploitation of some security vulnerabilities more
   87: difficult in some cases.
   88: 
   89: Two different mitigation levels are available:
   90: 
   91: * partial: the ELF sections are reordered so that internal data sections
   92:   precede the program's own data sections, and non-PLT GOT is read-only;
   93: * full: in addition to partial RELRO, every relocation is performed immediately
   94:   when starting the program (with a slight performance impact), allowing the
   95:   entire GOT to be read-only.
   96: 
   97: This is currently supported by GCC. Many software distributions now enable this
   98: feature by default, at the "partial" level.
   99: 
  100: More details can be found here:
  101: 
  102: * <https://www.redhat.com/en/blog/hardening-elf-binaries-using-relocation-read-only-relro>
  103: * <http://tk-blog.blogspot.co.at/2009/02/relro-not-so-well-known-memory.html>
  104: 
  105: ## Not enabled by default
  106: 
  107: ### PKGSRC_MKREPRO
  108: 
  109: With this option, pkgsrc will try to build packages reproducibly. This allows
  110: packages built from the same tree and with the same options, to produce
  111: identical results bit by bit. This option should be combined with ASLR and
  112: `PKGSRC_MKPIE` to avoid predictable address offsets for attackers attempting to
  113: exploit security vulnerabilities.
  114: 
  115: More details can be found here:
  116: 
  117: * <https://reproducible-builds.org/>
  118: 
  119: More work likely needs to be done before pkgsrc is fully reproducible.
  120: 
  121: ### PKGSRC_USE_STACK_CHECK
  122: 
  123: This uses `-fstack-check` with GCC for another stack protection mitigation.
  124: 
  125: It asks the compiler to generate code verifying that it does not corrupt the
  126: stack. According to GCC's manual page, this is really only useful for
  127: multi-threaded programs.
  128: 
  129: # Caveats
  130: 
  131: ## Problems with `PKGSRC_MKPIE`
  132: 
  133: ### Packages failing to build
  134: 
  135: A number of packages may fail to build with this option enabled. The failures
  136: are often related to the absence of the `-fPIC` compilation flag when building
  137: libraries or executables (or ideally `-fPIE` in the latter case). This flag is
  138: added to the `CFLAGS` already, but requires the package to actually support it.
  139: 
  140: #### How to fix
  141: 
  142: These instructions are meant as a reference only; they likely need to be adapted
  143: for many packages individually.
  144: 
  145: For packages using `Makefiles`:
  146: 
  147:     MAKE_FLAGS+=	CFLAGS=${CFLAGS:Q}
  148:     MAKE_FLAGS+=	LDFLAGS=${LDFLAGS:Q}
  149: 
  150: For packages using `Imakefiles`:
  151: 
  152:     MAKE_FLAGS+=	CCOPTIONS=${CFLAGS:Q}
  153:     MAKE_FLAGS+=	LOCAL_LDFLAGS=${LDFLAGS:Q}
  154: 
  155: ### Run-time crashes
  156: 
  157: Some programs may fail to run, or crash at random times once built as PIE. Two
  158: scenarios are essentially possible. This is nearly always due to a bug in
  159: the program being exposed due to ASLR.
  160: 
  161: ### Disabling PKGSRC_MKPIE on a per-package basis
  162: 
  163: Ideally, packages should be fixed for compatibility with MKPIE.
  164: However, in some cases this is very difficult, due to complex build systems,
  165: packages using non-standard toolchains, or programming languages with odd
  166: bootstrapping mechanisms.
  167: 
  168: To disable `PKGSRC_MKPIE` on a per-package basis, set `MKPIE_SUPPORTED= no` in the package's Makefile before `bsd.prefs.mk` is included.
  169: 
  170: ## Problems with `PKGSRC_USE_FORTIFY`
  171: 
  172: ### Packages failing to build
  173: 
  174: This feature makes use of pre-processing directives to look for hardened,
  175: alternative implementations of essential library calls. Some programs may fail
  176: to build as a result; this usually happens for those trying too hard to be
  177: portable, or otherwise abusing definitions in the standard library.
  178: 
  179: This will require a modification to the program, or disabling this feature
  180: by adding in the package `Makefile`:
  181: 
  182:     FORTIFY_SUPPORTED=	no
  183: 
  184: ### Run-time crashes
  185: 
  186: Just like with `PKGSRC_MKPIE` above, this feature may cause some programs to
  187: crash, usually indicating an actual bug in the program. The fix will typically
  188: involve patching the original program.
  189: 
  190: ### Optimization is required
  191: 
  192: At least in the case of GCC, FORTIFY will only be applied if optimization is
  193: applied while compiling. This means that the CFLAGS should also contain -O, -O2
  194: or another optimization level. This cannot easily be applied globally, as some
  195: packages may require specific optimization levels.
  196: 
  197: ## Problems with `PKGSRC_USE_RELRO`
  198: 
  199: ### Performance impact
  200: 
  201: For better protection, full RELRO requires every symbol to be resolved when the
  202: program starts, rather than simply when required at run-time. This will have
  203: more impact on programs using a lot of symbols, or linked to libraries exposing
  204: a lot of symbols. Therefore, daemons or programs otherwise running in
  205: background are affected only when started. Programs loading plug-ins at
  206: run-time are affected when loading the plug-ins.
  207: 
  208: The impact is not expected to be noticeable on modern hardware, except in some
  209: cases for big programs.
  210: 
  211: ### Run-time crashes
  212: 
  213: Some programs handle plug-ins and dependencies in a way that conflicts with
  214: RELRO: for instance, with an initialization routine listing any other plug-in
  215: required. With full RELRO, the missing symbols are resolved before the
  216: initialization routine can run, and the dynamic loader will not be able to find
  217: them directly and abort as a result. Unfortunately, this is how Xorg loads its
  218: drivers. Partial RELRO can be applied instead in this case.
  219: 
  220: ### Disabling RELRO on a per-package basis
  221: 
  222: To disable RELRO on a per-package basis, set `RELRO_SUPPORTED= no` in the package's Makefile before `bsd.prefs.mk` is included.
  223: 
  224: ## Problems with `PKGSRC_USE_SSP`
  225: 
  226: ### Packages failing to build
  227: 
  228: The stack-smashing protection provided by this option does not work for some
  229: programs. The most common situation in which this happens is when the program
  230: allocates variables on the stack, with the size determined at run-time.
  231: 
  232: Both cases will require a modification to the program, or disabling this feature
  233: by adding in the package `Makefile`:
  234: 
  235:     SSP_SUPPORTED=	no
  236: 
  237: ### Run-time crashes
  238: 
  239: Again, this feature may cause some programs to crash via a SIGABRT,
  240: usually indicating an actual bug in the program.
  241: 
  242: On NetBSD `LOG_CRIT` level `syslog()` messages are sent and - by
  243: default - appended to `/var/log/messages`, e.g.:
  244: 
  245:     Jan  6 15:42:51 <hostname> -: <hostname> <program> - - - buffer overflow detected; terminated
  246: 
  247: (where `<hostname>` is the `hostname(1)` and `<program>` is the
  248: `basename(1)` of the program crashed).
  249: 
  250: Patching the original program is then required.
  251: 
  252: Rebuilding the package via:
  253: 
  254:     % env CFLAGS=-g INSTALL_UNSTRIPPED=yes make replace
  255: 
  256: and inspecting the `backtrace` of the coredump via the debugger
  257: should point out the problematic call by inspecting the frame
  258: calling the `_chk()' (SSP) function.
  259: 
  260: ### Performance impact
  261: 
  262: The compiler emits extra code when using this feature: a check for buffer
  263: overflows is performed when entering and exiting functions, requiring an extra
  264: variable on the stack. The level of protection can otherwise be adjusted to
  265: affect only those functions considered more sensitive by the compiler (with
  266: `-fstack-protector` instead of `-fstack-protector-all`).
  267: 
  268: The impact is not expected to be noticeable on modern hardware. However,
  269: programs with a hard requirement to run at the fastest possible speed should
  270: avoid using this feature, or using libraries built with this feature.
  271: 
  272: # Auditing the system
  273: 
  274: The illusion of security is worse than having no security at all. This section
  275: lists a number of ways to ensure the security features requested are actually
  276: effective.
  277: 
  278: _These instructions were obtained and tested on a system derived from NetBSD 7
  279: (amd64). YMMV._
  280: 
  281: ## Checking for PIE
  282: 
  283: The ELF executable type in use changes for binaries built as PIE; without:
  284: 
  285:     $ file /path/to/bin/ary
  286:     /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
  287: 
  288: as opposed to the following binary, built as PIE:
  289: 
  290:     $ file /path/to/pie/bin/ary
  291:     /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
  292: 
  293: The latter result is then what is expected.
  294: 
  295: ## Checking for partial RELRO
  296: 
  297: The following command should list a section called `RELRO`:
  298: 
  299:     $ objdump -p /path/to/bin/ary
  300: 
  301:     /path/to/bin/ary:     file format elf64-x86-64
  302: 
  303:     Program Header:
  304:     [...]
  305:        RELRO off    0x0000000000000d78 vaddr 0x0000000000600d78 paddr 0x0000000000600d78 align 2**0
  306: 
  307: This check is now performed automatically if `PKG_DEVELOPER` is set and `RELRO`
  308: is enabled.
  309: 
  310: ## Checking for full RELRO
  311: 
  312: The dynamic loader will apply RELRO immediately when detecting the presence of
  313: the `BIND_NOW` flag:
  314: 
  315:     $ objdump -x /path/to/bin/ary
  316: 
  317:     /path/to/bin/ary:     file format elf64-x86-64
  318: 
  319:     Dynamic Section:
  320:     [...]
  321:       BIND_NOW             0x0000000000000000
  322: 
  323: This has to be combined with partial RELRO (see above) to be fully efficient.
  324: 
  325: ## Checking for SSP
  326: 
  327: Building objects, binaries and libraries with SSP will affect the presence of
  328: additional symbols in the resulting file:
  329: 
  330:     $ nm /path/to/bin/ary
  331:     [...]
  332:                      U __stack_chk_fail
  333:     0000000000600ea0 B __stack_chk_guard
  334: 
  335: This is an indicator that the program was indeed built with support for SSP.
  336: 
  337: This check is now performed automatically (where supported) if `PKG_DEVELOPER`
  338: is set and `SSP` is enabled.
  339: 
  340: If it is needed to disable SSP check per-package, please add in the package
  341: `Makefile`:
  342: 
  343:     CHECK_SSP_SUPPORTED=	no

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