MEMGUARD(9)

πŸ’– MEMGUARD(9) πŸ’–

okay bestie so we're in the Kernel Developer's Manual today and the topic is MemGuard β€” a memory allocator whose entire personality is debugging. yes, an allocator with a side quest. let's get into it πŸ¦‹


✨ NAME ✨

MemGuard β€” memory allocator for debugging purposes, no cap πŸŽ€


✨ SYNOPSIS ✨

options DEBUG_MEMGUARD

that's literally it. one line. iconic behavior πŸ’…


✨ DESCRIPTION ✨

so MemGuard is a simple and small replacement memory allocator, and its whole job is helping you detect tamper-after-free scenarios. and like… these problems are becoming more and more common and more likely, especially with multithreaded kernels where race conditions are just everywhere. it's giving chaos honestly 😭

here's the menu of what MemGuard can take over, pick your fighter:

  • it can take over malloc(), realloc() and free() for a single malloc type.
  • or it can take over uma_zalloc(), uma_zalloc_arg() and uma_free() for a single uma(9) zone.
  • it can also guard all allocations larger than PAGE_SIZE, bestie.
  • and it can guard a random fraction of all allocations. randomness! spice! ✨

there's also a knob to prevent allocations smaller than a specified size from being guarded, purely to limit memory waste. thoughtful queen 🌸


✨ EXAMPLES ✨

okay so if you wanna use MemGuard for a memory type, you've got two routes.

Route one: add an entry to /boot/loader.conf:

vm.memguard.desc=<memory_type>

Route two: set the vm.memguard.desc sysctl(8) variable at run-time:

sysctl vm.memguard.desc=<memory_type>

where memory_type can be either a short description of the memory type to monitor, either the name of a uma(9) zone. (yes, both options, she's flexible πŸ’–)

⚠️ important detail incoming: only allocations from that memory_type made after vm.memguard.desc is set will potentially be guarded. if you modify vm.memguard.desc at run-time, then only allocations of the new memory_type will potentially be guarded once the sysctl(8) is set. the existing guarded allocations will still be properly released by either free(9) or uma_zfree(9), depending on what kind of allocation was taken over. so no leaks, we're responsible here 🫢

now, how do you figure out the short description of a malloc(9) type? two ways, bestie:

  • take it from the first column of vmstat(8) -m output, or
  • find it in the kernel source. it's the second argument to the MALLOC_DEFINE(9) macro. iykyk πŸ”

and how do you find the name of a uma(9) zone? also two ways:

  • take it from the first column of vmstat(8) -z output, or
  • find it in the kernel source. it's the first argument to the uma_zcreate(9) function.

πŸ’œ the tunables πŸ’œ

the vm.memguard.divisor boot-time tunable is used to scale how much of the system's physical memory MemGuard is allowed to consume. the default is 10, so up to vm_cnt.v_page_count/10 pages can be used. MemGuard will reserve vm_kmem_max / vm.memguard.divisor bytes of virtual address space, limited by twice the physical memory size. and the receipts are public, periodt:

  • the physical limit is reported as vm.memguard.phys_limit
  • the virtual space reserved for MemGuard is reported as vm.memguard.mapsize

MemGuard will not do page promotions for any allocation smaller than vm.memguard.minsize bytes. the default is 0, meaning all allocations can potentially be guarded. 🌈

MemGuard can guard sufficiently large allocations randomly, with an average frequency of every one in 100000 / vm.memguard.frequency allocations. the default is 0, meaning no allocations are randomly guarded. so by default, zero random chaos. a calm queen.


MemGuard can optionally add unmapped guard pages around each allocation to detect overflow and underflow β€” if vm.memguard.options has the 1 bit set. this option is enabled by default. βœ…

MemGuard will optionally guard all allocations of PAGE_SIZE or larger β€” if vm.memguard.options has the 2 bit set. this option is off by default. ❌

by default, MemGuard does not guard uma(9) zones that have been initialized with the UMA_ZONE_NOFREE flag set, since it can produce false positives on them. (safety first, always πŸ›‘οΈ) however, this safety measure can be turned off by setting bit 3 of the vm.memguard.options tunable. you've been warned, bestie πŸ’€


✨ SEE ALSO ✨

sysctl(8), vmstat(8), contigmalloc(9), malloc(9), redzone(9), uma(9) β€” go read the whole friend group 🫢


✨ HISTORY ✨

MemGuard first appeared in FreeBSD 6.0. an OG. πŸ‘‘


✨ AUTHORS ✨

MemGuard was originally written by Bosko Milekic <bmilekic@FreeBSD.org>.

this manual page was originally written by Christian Brueffer <brueffer@FreeBSD.org>.

additions have been made by Matthew Fleming <mdf@FreeBSD.org> and Gleb Smirnoff <glebius@FreeBSD.org> to both the implementation and the documentation. multi-talented fr fr 🌟


and that's the whole page, bestie!! this one's from Debian, dated March 22, 2017, and it lives under MEMGUARD(9) β€” go guard some allocations responsibly, mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from