How Does Slab Poisoning Detect Memory Bugs? – Free Linux Device Drivers Training Online

Linux Kernel Slab Allocator Debugging Tutorial
SLUB Debug, Poisoning, Redzoning & KASAN Explained for Modern Kernels — Free Linux Kernel Development Course
Level
Beginner to Intermediate
Kernel Version
6.x (current)
Category
Linux Kernel Memory Management

What You Will Learn

Memory corruption bugs are among the hardest problems a kernel or device driver developer will ever chase. In this lesson from our free Linux kernel development course, you will learn how the kernel’s slab allocator helps you catch these bugs before they take down a production system. By the end of this tutorial you will understand:

  • Why kernel memory debugging matters for driver and module authors
  • How the slab allocator evolved — and why only one implementation exists in current kernels
  • How to turn on slab debugging using today’s slab_debug boot parameter
  • What slab poisoning and redzoning actually do, in plain language
  • How KASAN and kmemleak fit into a modern debugging workflow
  • Best practices, common mistakes, and performance trade-offs

Prerequisites
Basic C programming
Linux command line
kmalloc / kfree basics
Kernel module building

If you are new to kernel memory allocation, we recommend completing the earlier lecture on kernel memory allocation basics first, then returning to this one. Links to that lecture will be added at the top and bottom of this page.

This lecture is part of our free Linux kernel development course, free Linux device drivers course, and free embedded systems course.

slab allocator debugging
SLUB debug
slab poisoning
KASAN
kmemleak
kernel memory corruption

Why Slab Allocator Debugging Matters

Every time a driver calls kmalloc(), kzalloc(), or allocates from a custom cache, it is borrowing memory from the slab allocator. If that driver writes past the end of an allocated buffer, reads memory it never initialized, or touches memory after freeing it, the bug usually does not crash the system right away. Instead it silently corrupts a neighboring object, and the crash shows up minutes or hours later, deep inside completely unrelated code. This is exactly why the kernel ships built-in tooling to catch these problems close to their source, rather than at the point where the corrupted data finally causes a visible failure.

Understanding slab allocator debugging is a core skill for anyone writing Linux device drivers, kernel modules, or working on embedded Linux platforms where every allocation matters.

The Slab Allocator Landscape Has Changed

Older references describe three competing slab allocator implementations in the Linux kernel: SLAB, SLOB, and SLUB. This is no longer accurate, and it is one of the most important updates for anyone learning kernel memory debugging today. SLOB was removed in kernel 6.4, and SLAB was removed in kernel 6.8. Since then, SLUB is the only slab allocator implementation in mainline Linux, and it now covers use cases (including very small memory systems, via the SLUB_TINY configuration) that previously needed a separate allocator.

Slab Allocator History
SLOB
Removed in kernel 6.4
SLAB
Removed in kernel 6.8
SLUB
Sole allocator, current kernels

This matters practically: if you are following an older book or tutorial that talks about choosing between SLAB and SLUB in kernel config, that step no longer exists on a current kernel. All slab debugging today happens through SLUB’s own facilities.

Enabling Slab Debugging on a Current Kernel

To use SLUB’s built-in debug features, the kernel must be built with CONFIG_SLUB_DEBUG=y. This is enabled on virtually every distribution kernel by default. You can confirm it on your own machine like this:

grep -w CONFIG_SLUB_DEBUG /boot/config-$(uname -r)

A result of CONFIG_SLUB_DEBUG=y confirms the feature is compiled in. Having it compiled in does not mean it is active, though — SLUB debugging is off by default for performance reasons and must be switched on explicitly.

On current kernels, this is done using the slab_debug kernel command-line parameter. Note that this replaces the older slub_debug naming used in earlier kernel releases, which was renamed once SLUB became the kernel’s only slab allocator.

slab_debug=FZPU

Each letter turns on one category of checking:

Flag What It Enables
F Sanity checks on cache consistency
Z Redzoning around each object
P Poisoning of object and padding memory
U User tracking (records the last allocator/freer)
T Tracing (very verbose — use on a single cache only)
– Disable all debugging for caches where it was enabled by default

You can also target a single slab cache instead of enabling debugging system-wide, which is far more practical when you already suspect where a bug lives:

slab_debug=FZ,dentry

This applies sanity checks and redzoning only to the dentry cache, leaving every other cache running at full speed.

Slab Poisoning and Redzoning, Explained Simply

Think of poisoning as painting freshly allocated or just-freed memory with a very distinctive, unmistakable color. If that color ever changes unexpectedly, you instantly know something touched memory it should not have. That is the entire idea behind slab poisoning.

When the P flag is active, every object handed out by the allocator is first filled with a recognizable byte pattern. If your driver reads that memory before writing to it — a classic uninitialized memory read — the pattern shows up in the value it reads, which is an unmistakable signal of a bug. Likewise, once an object is freed, SLUB rewrites it with a different signature pattern. If any code later writes to that freed memory, the pattern gets disturbed, and SLUB’s sanity checks (the F flag) can flag the corruption the next time that slab is examined — a strong indicator of a use-after-free bug.

Object Memory Layout Under SLUB Debug
Left
Redzone
Object Payload
(poisoned when unused)
Right
Redzone
Padding
(alignment)

Redzoning works differently, but it complements poisoning well. Instead of filling the object itself, SLUB places small guard regions immediately before and after each object and fills them with a fixed value. These guard regions do not belong to your data at all — they exist purely as tripwires. If your driver writes even one byte past the end of a buffer it allocated, that write lands in the redzone, and SLUB’s consistency checks will catch the change, pointing directly at a buffer overflow rather than letting it silently corrupt the next object in memory.

Tip: Poisoning tells you what kind of bug occurred (uninitialized read vs. use-after-free); redzoning tells you where the boundary violation happened. Used together, they give you a fast first diagnosis before you even open a debugger.

Where KASAN Fits In Today’s Workflow

SLUB debug is extremely useful, but it is not the strongest tool available on a current kernel. Most kernel developers today reach first for KASAN (the Kernel Address Sanitizer) when hunting memory bugs, because it catches a much wider range of issues — including out-of-bounds accesses on the stack and globals, not only slab objects — and reports the exact allocation and free call stacks responsible.

KASAN has three operating modes on modern kernels:

Mode Overhead Best Used For
Generic KASAN High (2x–3x memory, slower) Development and CI test kernels
Software Tag-Based KASAN Moderate Arm64 development boards
Hardware Tag-Based KASAN (MTE) Low Newer Arm64 hardware, closer to production testing

A practical rule of thumb for driver development: use KASAN on your development and test kernels whenever possible, since it finds bugs earlier and with clearer stack traces. Reach for SLUB’s own slab_debug flags when you need something lightweight enough to run continuously, or when you are debugging on a target where KASAN’s overhead is not acceptable.

Catching Leaks with kmemleak

Poisoning and redzoning catch corruption, but they will not tell you about memory that is allocated and simply never freed. That is what kmemleak is for. It periodically scans kernel memory looking for allocated blocks with no remaining pointer to them anywhere in the system, and reports them as probable leaks. It is not perfect — like a garbage collector’s leak detector, it can occasionally report false positives — but it remains one of the most convenient ways to catch a driver that forgets to call kfree() on an error path.

# Trigger an on-demand kmemleak scan and view results
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak

A Practical Debugging Workflow
Choosing the Right Tool
Suspect memory corruption or a leak?
↓
On a dev/test kernel with spare resources → Enable KASAN
Need lightweight, targeted checks → Use slab_debug=FZPU,cache_name
Suspect a missing kfree() → Scan with kmemleak

Real-World Use Cases
  • New driver bring-up: Enable KASAN on your test board’s kernel while developing a new driver so bounds and use-after-free bugs surface immediately instead of during field testing.
  • Intermittent production crashes: Narrow debugging to a single suspect cache with slab_debug=FZ,cache_name on a staging system, since full system-wide debugging is usually too costly for production-like environments.
  • Long-running embedded systems: Run periodic kmemleak scans on embedded Linux devices that stay powered on for months, where a slow leak eventually exhausts memory.

Common Mistakes and Troubleshooting Tips
Mistake Why It Hurts Fix
Enabling full slab_debug on a production system Significant performance hit and higher memory use Target specific caches, or use KASAN only on test kernels
Installing a custom constructor and expecting poisoning Poisoning on allocation does not apply the same way when a custom constructor is present Understand your cache’s constructor behavior before relying on poison values
Assuming the first symptom is the root cause Memory corruption often shows up far from where it was actually caused Use user tracking (U flag) or KASAN stack traces to find the real allocation/free site
Referring to outdated SLAB vs SLUB tuning advice SLAB no longer exists in current kernels Base your configuration decisions on SLUB-only documentation for your running kernel version

Best Practices
  • Develop and run CI test suites with KASAN enabled whenever you have the hardware headroom for it.
  • Reserve full-system slab_debug for short, focused debugging sessions rather than everyday use.
  • Pair redzoning with user tracking so a report gives you both the boundary violation and the responsible call stack.
  • Re-check your kernel version’s documentation before applying advice from older books or blog posts, since slab allocator internals have changed substantially in recent releases.
  • Run kmemleak scans on long-uptime systems as part of routine health checks, not only when you already suspect a leak.

Performance and Security Considerations

Performance: Every debug feature you turn on costs something. Sanity checks and user tracking add CPU overhead on every allocation and free. Poisoning and redzoning also increase the memory footprint of each object because of the extra guard bytes and metadata. Generic KASAN has the highest cost of all the tools discussed here, often doubling or tripling memory usage, which is why it is normally reserved for development and testing rather than shipped in production kernels.

Security: Slab debugging is a development and diagnostic aid, not a production hardening feature by itself. That said, understanding how object layout, redzones, and poisoning work is directly useful for security engineers auditing kernel code for heap overflow and use-after-free vulnerabilities, since these are exactly the bug classes attackers most commonly target in kernel exploitation.

Summary / Key Takeaways
  • Current kernels have a single slab allocator implementation, SLUB — SLOB and SLAB have both been removed.
  • Slab debugging is off by default and enabled with the slab_debug kernel boot parameter.
  • Poisoning marks unused and freed memory with recognizable patterns to catch uninitialized reads and use-after-free bugs.
  • Redzoning places guard bytes around each object to catch buffer overflows at the exact boundary.
  • KASAN is generally the stronger tool for development kernels; SLUB’s own debug flags are lighter weight and can be targeted at a single cache.
  • kmemleak complements both by catching memory that is allocated but never freed.

Conclusion

Kernel memory bugs are rarely obvious at the point where they happen — that is precisely why the slab allocator’s built-in debugging tools exist. Once you understand what poisoning and redzoning are actually protecting against, reading a corruption report stops being intimidating and starts being a straightforward diagnostic process. Combine SLUB’s targeted debug flags with KASAN during development and kmemleak for leak detection, and you will have a debugging workflow that scales from a quick driver bring-up all the way to chasing a rare production issue.

Frequently Asked Questions

1. Is SLAB still used in current Linux kernels?
No. SLOB was removed in kernel 6.4 and SLAB was removed in kernel 6.8. SLUB is now the only slab allocator in mainline Linux.

2. What replaced the slub_debug boot parameter?
Current kernel documentation refers to it as slab_debug, reflecting that SLUB is now simply “the” slab allocator rather than one of several.

3. Does enabling slab debugging slow down my system?
Yes, to varying degrees depending on which flags you enable. Sanity checks, tracing, and user tracking add CPU overhead, while poisoning and redzoning increase memory usage per object.

4. What is the difference between poisoning and redzoning?
Poisoning fills the object’s own memory with a recognizable pattern to catch uninitialized reads and use-after-free writes. Redzoning adds separate guard bytes around the object to catch out-of-bounds writes at its boundaries.

5. Should I use KASAN or SLUB debug flags?
Use KASAN on development and test kernels when you can afford the overhead, since it catches a broader range of bugs with clearer stack traces. Use targeted SLUB debug flags when you need something lighter or want to check a single suspect cache.

6. Can I enable debugging for only one slab cache?
Yes. You can pass a cache name after the debug flags, for example slab_debug=FZ,dentry, to limit the performance impact to that cache alone.

7. What does kmemleak actually detect?
It detects memory blocks that remain allocated with no reachable pointer to them anywhere in kernel memory, which is a strong indicator of a memory leak.

8. Is this tutorial applicable to embedded Linux boards?
Yes. All of these tools work on embedded ARM and other architectures supported by the mainline kernel, though KASAN’s memory overhead should be considered carefully on RAM-constrained boards.

9. Do I need special hardware to use KASAN?
Generic and software tag-based KASAN run on standard hardware. Hardware tag-based KASAN requires Arm64 silicon with Memory Tagging Extension (MTE) support.

10. Where can I learn more about writing kernel modules that avoid these bugs in the first place?
Continue with the next lecture in this free Linux kernel development course, linked at the top and bottom of this page, once it is available.

Continue Your Free Linux Kernel Development Course

More free lessons on Linux kernel programming, device drivers, and embedded systems are on the way.

Browse the Course

Leave a Reply

Your email address will not be published. Required fields are marked *