MITIGATIONS(7)

πŸ“¦
version 15.1 Β· 2 versions
, in freebsd 15.1, nixpkgs unstable

πŸ’– NAME πŸ’–

mitigations β€” FreeBSD Security Vulnerability Mitigations

✨ SYNOPSIS ✨

okay so bestie, here's the vibe: in FreeBSD, a whole bunch of security mitigations are employed to limit the impact of vulnerabilities and protect the system from malicious attacks. some of these mitigations have run-time controls so you can turn them on globally or per-process, some are optionally enabled or disabled at compile time, and some are just inherent to the implementation with no controls at all (they just are, main character energy, no notes πŸ’…).

the following vulnerability mitigations are covered in this document:

  • Address Space Layout Randomization (ASLR)
  • Position Independent Executable (PIE)
  • Write XOR Execute page protection policy
  • PROT_MAX
  • Relocation Read-Only (RELRO)
  • Bind Now
  • Stack Overflow Protection
  • Supervisor Mode Memory Protection
  • Capsicum
  • Firmware and Microcode
  • Architectural Vulnerability Mitigations
heads up 🫢 the effectiveness and availability of these mitigations may vary depending on the FreeBSD version and system configuration. so don't come for me if your box is built different.

πŸ¦‹ DESCRIPTION πŸ¦‹

security vulnerability mitigations are the techniques FreeBSD employs to limit the potential impact of security vulnerabilities in software and hardware. but listen β€” it's essential to understand that mitigations do not directly address the underlying security issues. they are not a substitute for secure coding practices. ngl, they're an additional layer of defense: they help reduce the likelihood of a successful exploitation of vulnerabilities by making it more difficult for attackers to achieve their objectives. it's giving "locked door plus a barking dog plus a ring camera" β€” not a replacement for actually fixing the lock πŸ”₯

this manual page describes the security mitigations implemented in FreeBSD to enhance the overall security of the operating system. each mitigation is designed to protect against specific types of attacks and vulnerabilities. periodt.


πŸ‘‘ SOFTWARE VULNERABILITY MITIGATIONS πŸ‘‘

🌈 Address Space Layout Randomization (ASLR)

Address Space Layout Randomization (ASLR) is a security mitigation technique that works by randomizing the memory addresses where system and application code, data, and libraries are loaded β€” making it more challenging for attackers to predict the memory layout and exploit vulnerabilities. it's literally shuffling the deck every single time πŸ”€

ASLR introduces randomness into the memory layout during process execution, reducing the predictability of memory addresses. it's intended to make exploitation more difficult in the event that an attacker discovers a software vulnerability, such as a buffer overflow.

ASLR can be enabled on both a global and per-process basis. global control is provided by a separate set of sysctl(8) knobs for 32- and 64-bit processes. it can be enabled or disabled on a per-process basis via proccontrol(1). note that an ASLR mode change takes effect upon address space change, i.e., upon execve(2) β€” so no, flipping the switch doesn't retroactively fix the process you're already in, sorry bestie 😭

Global controls for 32-bit processes:

  • kern.elf32.aslr.enable β€” Enable ASLR for 32-bit ELF binaries, other than Position Independent Executable (PIE) binaries.
  • kern.elf32.aslr.pie_enable β€” Enable ASLR for 32-bit Position Independent Executable (PIE) ELF binaries.
  • kern.elf32.aslr.honor_sbrk β€” Reserve the legacy sbrk(2) region for compatibility with older binaries.
  • kern.elf32.aslr.stack β€” Randomize the stack location for 32-bit ELF binaries.

Global controls for 64-bit processes:

  • kern.elf64.aslr.enable β€” Enable ASLR for 64-bit ELF binaries, other than Position Independent Executable (PIE) binaries.
  • kern.elf64.aslr.pie_enable β€” Enable ASLR for 64-bit Position Independent Executable (PIE) ELF binaries.
  • kern.elf64.aslr.honor_sbrk β€” Reserve the legacy sbrk(2) region for compatibility with older binaries.
  • kern.elf64.aslr.stack β€” Randomize the stack location for 64-bit ELF binaries.

to execute a command with ASLR enabled or disabled:

proccontrol -m aslr [-s enable | disable] command

slay. go forth and randomize πŸ’œ

πŸŽ€ Position Independent Executable (PIE)

PIE binaries are executable files that do not have a fixed load address. they can be loaded at an arbitrary memory address by the rtld(1) run-time linker. with ASLR they are loaded at a random address on each execution. iconic behaviour, honestly β€” no fixed address, no fixed vibe ✨

πŸ’€ Write XOR Execute page protection policy

Write XOR Execute (W^X) is a vulnerability mitigation strategy that strengthens the security of the system by controlling memory access permissions.

under the W^X mitigation, memory pages may be writable (W) or executable (E), but not both at the same time. this means code execution is prevented in areas of memory that are designated as writable, and writing or modification of memory is restricted in areas marked for execution. applications that perform Just In Time (JIT) compilation need to be adapted to be compatible with W^X β€” yes, your JIT people have homework, that's just how it is πŸ™ˆ

there are separate sysctl(8) knobs to control W^X policy enforcement for 32- and 64-bit processes. the W^X policy is enabled by setting the appropriate allow_wx sysctl to 0.

  • kern.elf32.allow_wx β€” Allow 32-bit processes to map pages simultaneously writable and executable.
  • kern.elf64.allow_wx β€” Allow 64-bit processes to map pages simultaneously writable and executable.

πŸ“ PROT_MAX

PROT_MAX is a FreeBSD-specific extension to mmap(2). PROT_MAX provides the ability to set the maximum protection of a region allocated by mmap(2) and later altered by mprotect(2). for example, memory allocated originally with an mmap prot argument of PROT_MAX(PROT_READ | PROT_WRITE) | PROT_READ may be made writable by a future mprotect(2) call, but may not be made executable. it's giving "you can grow, but only this much" 🌱

🧚 Relocation Read-Only (RELRO)

Relocation Read-Only (RELRO) is a mitigation tool that makes certain portions of a program's address space that contain ELF metadata read-only, after relocation processing by rtld(1).

when enabled in isolation the RELRO option provides partial RELRO support. in this case the Procedure Linkage Table (PLT)-related part of the Global Offset Table (GOT) (in the section typically named .got.plt) remains writable. partial slay, we love a work in progress πŸ’…

RELRO is enabled by default. the src.conf(5) build-time option WITHOUT_RELRO may be used to disable it.

⭐ BIND_NOW

the WITH_BIND_NOW src.conf(5) build-time option causes binaries to be built with the DF_BIND_NOW flag set. the run-time loader rtld(1) will then perform all relocation processing when the process starts, instead of on demand (on the first access to each symbol). no more "do it later", it's all done up front πŸ”₯

when enabled in combination with RELRO (which is enabled by default) this provides full RELRO. the entire GOT (.got and .got.plt) are made read-only at program startup, preventing attacks on the relocation table.

the caveat tho 😭 note that this results in a nonstandard Application Binary Interface (ABI), and it is possible that some applications may not function correctly. so like... test your stuff, bestie.

🌸 Stack Overflow Protection

FreeBSD supports stack overflow protection using the Stack Smashing Protector (SSP) compiler feature. stack clash protection is also enabled, if supported by the compiler for the given architecture. in userland, SSP adds a per-process randomized canary at the end of every stack frame which is checked for corruption upon return from the function, and stack probing in PAGE_SIZE chunks. in the kernel, a single randomized canary is used globally β€” except on aarch64, which has a PERTHREAD_SSP config(8) option to enable per-thread randomized canaries. if stack corruption is detected, then the process aborts to avoid potentially malicious execution as a result of the corruption. SSP may be enabled or disabled when building FreeBSD base with the src.conf(5) SSP knob.

when WITH_SSP is enabled, which is the default, world is built with the -fstack-protector-strong and -fstack-clash-protection compiler options. the kernel is built with the -fstack-protector option.

in addition to SSP, a β€œFORTIFY_SOURCE” implementation is supported up to level 2 by defining _FORTIFY_SOURCE to 1 or 2 before including any FreeBSD headers. FreeBSD world builds can set FORTIFY_SOURCE in the environment or /etc/src-env.conf to provide a default value for _FORTIFY_SOURCE. when enabled, β€œFORTIFY_SOURCE” enables extra bounds checking in various functions that accept buffers to be written into. these functions currently have extra bounds checking support:

bcopy()      bzero()     fgets()     getcwd()      gets()
memcpy()     memmove()   memset()    read()        readlink()
snprintf()   sprintf()   stpcpy()    stpncpy()     strcat()
strcpy()     strncat()   strncpy()   vsnprintf()   vsprintf()

β€œFORTIFY_SOURCE” requires compiler support from clang(1) or gcc(1), which provide the __builtin_object_size(3) function that is used to determine the bounds of an object. this feature works best at optimization levels -O1 and above, as some object sizes may be less obvious without some data that the compiler would collect in an optimization pass. lowkey the optimizer is doing the lord's work here 🫢

similar to SSP, violating the bounds of an object will cause the program to abort in an effort to avoid malicious execution. this effectively provides finer-grained protection than SSP for some class of function and system calls, along with some protection for buffers allocated as part of the program data. ate and left no crumbs ✨

πŸ¦‹ Supervisor mode memory protection

certain processors include features that prevent unintended access to memory pages accessible to userspace (non-privileged) code, while in a privileged mode. one feature prevents execution, intended to mitigate exploitation of kernel vulnerabilities from userland. another feature prevents unintended reads from or writes to user space memory from the kernel. this also provides effective protection against NULL pointer dereferences from kernel. so the kernel stops tripping over userland's stuff πŸ’€

  • amd64 β€” SMAP β€” Read / Write prevented
  • amd64 β€” SMEP β€” Execute prevented
  • arm64 β€” PAN β€” Read / Write prevented
  • arm64 β€” PXN β€” Execute prevented
  • riscv β€” SUM β€” Read / Write prevented
  • riscv β€” - β€” Execute prevented

these features are automatically used by the kernel. there is no user-facing configuration. nothing to toggle, nothing to stress about, it's just on πŸ‘‘

πŸŽ€ Capsicum

Capsicum is a lightweight OS capability and sandbox framework. see capsicum(4) for more information.


so that's the software mitigation tour bestie β€” the hardware chaos, firmware, microcode and architectural mitigations are still queued up, and trust, there's more where that came from πŸ’œ

πŸ’– HARDWARE VULNERABILITY MITIGATIONS πŸ’–

🧚 Firmware and Microcode

Ok so bestie, buckle up: recent years have been giving unending stream of new hardware vulnerabilities 😭 β€” and the CPU ones especially, because they're generally caused by detectable microarchitectural side-effects of speculative execution that leak private data from some other thread or process, or sometimes even internal CPU state that's normally just... not accessible to you. Rude.

Hardware vendors usually deal with these as they get discovered by dropping microcode updates, which then get bundled into platform firmware updates (historically called BIOS updates for PCs 🌈) or into packages that the operating system updates at boot time.

Platform firmware updates, if the manufacturer still has them, are the best defense β€” they give you coverage during early boot. Install them with sysutils/flashrom from the FreeBSD Ports Collection ✨.

If platform firmware updates are no longer available, packaged microcode is available to install at sysutils/cpu-microcode and can be loaded at runtime using loader.conf(5) β€” peep the package message for more deets 🫢.

The best defense overall against hardware vulnerabilities is to timely apply these updates when they're available, as early as possible in the boot process, and to disable the affected hardware's problematic functionalities when you can (e.g., CPU Simultaneous Multi-Threading). Software mitigations are only partial substitutes for all of that, but they can be helpful on out-of-support hardware or as complements for just-discovered vulnerabilities that vendors haven't addressed yet. Some software mitigations literally depend on hardware capabilities provided by a microcode update πŸ‘‘

πŸ¦‹ Architectural Vulnerability Mitigations

FreeBSD's usual policy is to apply by default all OS-level mitigations that don't require recompilation β€” except those the particular hardware it's running on is known not to be vulnerable to (which sometimes requires firmware updates), or those that are extremely detrimental to performance in proportion to the protection they actually provide πŸ’€.

OS-level mitigations generally can have noticeable performance impacts on specific workloads. If your threat model allows it, you may want to try disabling some of them to possibly get better performance. Conversely, minimizing the risks may require you to explicitly enable the most expensive ones 😀. The description of each vulnerability/mitigation tells you whether it's enabled or disabled by default and under which conditions, and it also lists the knobs to tweak to force a particular status.


🌸 Zenbleed

The "Zenbleed" vulnerability exclusively affects AMD processors based on the Zen2 microarchitecture. In contrast with, e.g., Meltdown and the different variants of Spectre β€” which leak data by leaving microarchitectural traces β€” Zenbleed is a genuine hardware bug affecting the CPU's architectural state 😳. With particular sequences of instructions whose last ones are mispredicted by speculative execution, it's possible to make data appear in an XMM register that was previously put in some XMM register by some preceding or concurrent task executing on the same physical core (so disabling Simultaneous Muti-Threading (SMT) is not a sufficient protection, bestie).

According to the vulnerability's discoverer, all Zen2-based processors are affected (see https://lock.cmpxchg8b.com/zenbleed.html). As of August 2023, AMD has not publicly listed any corresponding errata but has issued a security bulletin (AMD-SB-7008) entitled "Cross-Process Information Leak" indicating that platform firmware fixing the vulnerability will be distributed to manufacturers no sooner than the end of 2023 β€” except for Rome processors, for which it is already available. No standalone CPU microcodes have been announced so far. The only readily-applicable fix mentioned by the discoverer is to set a bit of an undocumented MSR, which reportedly completely stops XMM register leaks ✨.

FreeBSD currently sets this bit by default on all Zen2 processors. In the future, it might set it by default only on those Zen2 processors whose microcode has not been updated to revisions fixing the vulnerability, once such microcode updates have actually been released and community-tested. To this mitigation are associated the following knobs:

  • machdep.mitigations.zenbleed.enable β€” a read-write integer tunable and sysctl indicating whether the mitigation should be forcibly disabled (0), enabled (1) or left to FreeBSD to selectively apply it (2). Any other integer value is silently converted to and treated as value 2. Note that this setting is silently ignored when running on non-Zen2 processors, to ease applying a common configuration to heterogeneous machines 🫢
  • machdep.mitigations.zenbleed.state β€” a read-only string indicating the current mitigation state. It can be either "Not applicable", if the processor is not Zen2-based, "Mitigation enabled" or "Mitigation disabled". This state is automatically updated each time the sysctl machdep.mitigations.zenbleed.enable is written to. Note that it can become inaccurate if the chicken bit is set or cleared directly via cpuctl(4) (which includes the cpucontrol(8) utility) πŸ™ˆ

The performance impact and threat models related to these mitigations should be considered when configuring and deploying them in a FreeBSD system.

Additional mitigation knobs are listed in the "KNOBS AND TWEAKS" section of security(7).


🌈 SEE ALSO

elfctl(1), proccontrol(1), rtld(1), mmap(2), src.conf(5), sysctl.conf(5), security(7), cpucontrol(8), sysctl(8) πŸŽ€


That's a wrap, bestie!! This page is from Debian, dated January 29, 2025, and it's literally MITIGATIONS(7) β€” go forth and mitigate responsibly πŸ’œπŸ‘‘

πŸ“¦ where this page comes from