I'm writing this in the process of learning, so some information may be misleading or wrong. If you have any corrections or suggested topics, I'd love to hear them (mmcco@mykolab.com). -- BSD kernels use a malloc/free dynamic allocation interface similar to userland's. However, the interface is richer to allow for greater performance and stability. This is a consequence of kernel-level allocation being both more nuanced and more performance-critical. There is no formal or informal specification for kernel-level allocation interfaces, so each Unix-like kernel's is different. Unix-like kernels also have multiple allocation interfaces, some optimized for specific use cases.[1] I'll present OpenBSD's kernel malloc/free first and mention other interfaces when relevant. Here's the man page for the OpenBSD kernel's allocator: http://man.openbsd.org/free.9 The main API difference between userland malloc and kernel malloc is that the latter takes flags as an argument. These flags allows kernel programmers to choose between two error-handling behaviors: 1. Block until memory is available (M_WAITOK) 2. Return NULL if memory is unavailable (M_NOWAIT) M_NOWAIT is the behavior of userland malloc. == Userland malloc == Userland malloc may block briefly while waiting for a mutex but never sleeps. Barring an internal error (which will probably abort the process anyway), it will only fail when the system is out of memory. Modern machines have a lot of RAM and as much swap, so this case is very rare and often can't be handled easily. Therefore, below is the proper idiom for almost all userland malloc uses: if ((buf = malloc(sz)) == NULL) /* * This prints "myprog: Cannot allocate memory" to * stderr and exits with error code 1. */ err(1, NULL); That is: if the allocation fails, exit immediately. Less cautious (and often, dangerous) programs don't check the return status at all. In this case, a null pointer dereference will hopefully crash the program before anything unintended happens. However, dereferencing a null pointer is undefined (C11 6.5.3.2), so the compiler is free to generate code that leaves you scratching your head when debugging, or that leaves you submitting a CVE. The other, rarer approach is to actually handle the error. This makes sense in some contexts, particularly in core system libraries. For example, network daemons and the libraries they use are free to reject or terminate certain connections. If there isn't space available to initialize the data structures necessary for TLS encryption, libssl can simply indicate this to your server daemon by returning NULL. The server can then reject the connection or return a 503 without dying. We have to be careful when gracefully handling allocation error, though. This is because allocation will rarely or never occur in testing, and the error handling paths can therefore contain nonsensical or dangerous code. These are commonly unearthed by manual auditing or static analysis. Here's an example that I merged from BoringSSL to LibreSSL: https://secure.freshbsd.org/commit/openbsd/87fcd852fe4bcadd406463f7cecb843d4149eb76 X509_EXTENSION_set_object() was supposed to report allocation failure and the functions calling it assumed this, but it just assumed that the allocation always succeeded. In the worst case, erroneous non-fatal handling of allocation failure can make your program exploitable if an attacker can exhaust your system's memory. In practice, this often means they just have to find a memory leak in an exposed program on the system. Rust's standard library takes this a step further, baking the abort-if-null logic into the syntax used for dynamic allocation.[2] This complicates kernel development somewhat, as we'll soon see. == Kernel malloc == Kernels present a different situation. Unallocated kernel memory is used for caching code and disk data, and some kernel memory can't be swapped to disk. Because of this, it's likely that memory will be unavailable when malloc is called but can be made available soon by flushing caches. [...] == Further reading == http://www.linuxjournal.com/article/6930 https://www.win.tue.nl/~aeb/linux/lk/lk-9.html https://lwn.net/Articles/627419/ == Footnotes == [1] For example, see NetBSD's kmem_alloc(9). [2] Similarly, many programs implement the non-standard function xmalloc, which simply calls malloc and aborts the program if malloc fails.