MEMGUARD(9)

πŸ“¦ version 15.1, in freebsd 14.5, freebsd 15.1, nixpkgs unstable

πŸ’– MEMGUARD(9) β€” the Kernel Developer's Manual, but make it a group chat πŸ’–

okay so bestie, you're reading MEMGUARD(9) from the Kernel Developer's Manual and honestly? this one's a bop. it's the memory allocator that exists purely to catch bugs being messy. let's get into it 🧚✨


πŸŽ€ NAME πŸŽ€

MemGuard β€” a memory allocator for debugging purposes. literally that's her job. that's the whole vibe πŸ’…


✨ SYNOPSIS ✨

options DEBUG_MEMGUARD

no cap, that's it. one line. iconic.


🌸 DESCRIPTION 🌸

so MemGuard is a simple and small replacement memory allocator, and she was designed to help detect tamper-after-free scenarios. and ngl, these problems are more and more common and likely with multithreaded kernels where race conditions are more prevalent 😭 like the vibes are chaotic in there.

here's the menu of what MemGuard can take over, bestie:

  • she can take over malloc(), realloc() and free() for a single malloc type, OR
  • she can take over uma_zalloc(), uma_zalloc_arg() and uma_free() for a single uma(9) zone, OR
  • she can guard all allocations larger than PAGE_SIZE, and
  • she can guard a random fraction of all allocations.

there's also a knob to prevent allocations smaller than a specified size from being guarded, so you don't waste memory like it's going out of style. we love a queen who's mindful of the budget 🫢


πŸ¦‹ EXAMPLES πŸ¦‹

πŸ’œ guarding a memory type

to use MemGuard for a memory type, either add an entry to /boot/loader.conf:

vm.memguard.desc=<memory_type>

or 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, or the name of a uma(9) zone. (yes, either/or, she's flexible ✨)

the important detail, and do NOT skip this one: only allocations from that memory_type made after vm.memguard.desc is set will potentially be guarded. if vm.memguard.desc is modified at run-time then only allocations of the new memory_type will potentially be guarded once the sysctl(8) is set. but β€” and this is the slay part β€” 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. no leaks, no drama πŸ’…

πŸ“ how to find your memory_type

to determine the short description of a malloc(9) type, you can either:

  • 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.

to determine the name of a uma(9) zone, you can either:

  • 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.

iykyk πŸ‘‘

🌈 the vm.memguard.divisor tunable

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.
  • the physical limit is reported as vm.memguard.phys_limit.
  • the virtual space reserved for MemGuard is reported as vm.memguard.mapsize.

look at her, reporting her own numbers. transparent queen πŸ”₯

🧚 page promotions + random guarding

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.

πŸ‘‘ vm.memguard.options β€” the bit flags, bestie

okay this is the part where you pay attention because bits are involved πŸ™ˆ

  • 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. however, this safety measure can be turned off by setting bit 3 of the vm.memguard.options tunable.
turning off a safety measure is a choice, bestie. a bold one. do with that what you will πŸ’€

⭐ SEE ALSO ⭐

sysctl(8), vmstat(8), contigmalloc(9), malloc(9), redzone(9), uma(9)

go read them all, they're all connected, it's giving lore πŸ¦‹


πŸŽ€ HISTORY πŸŽ€

MemGuard first appeared in FreeBSD 6.0. a legend since day one, fr fr πŸ’–


πŸ’œ 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.

collab of the century honestly 🌈✨


and that's the page, bestie! this particular edition shipped with Debian, dated March 22, 2017 β€” so if anyone asks where this lore came from, that's the receipt 🫢🌸 you're welcome, go guard some memory πŸ’…

πŸ“¦ where this page comes from