SLUB_DEBUG is not designed as a security feature and shouldn't actually be enabled in production on hardened systems. The redzone implementation fills spare padding space with a standard value and checks for it, then reports corruption when detected at free and attempts to recover. A security feature needs to guarantee a certain size of canary is present rather than only being opportunistic, should use a random value to prevent concealing a sequential overflow by matching the padding value and should use a leading zero to reliably contain string overflows like the Linux kernel stack canaries now do. Bug detection vs. security makes the implementation quite different very much like init on free / init on alloc vs. page/slab poisoning. It was accepted for that, and I think it should be accepted upstream for this too if someone is willing to deal with the hassle of trying to upstream it.
In linux-hardened, there's an implementation of random canaries that are 4 bytes on 32-bit and 8 bytes on 64-bit with a leading zero on 64-bit to reliably contain string function overflows both to prevent overflowing elsewhere and to protect leaking the canaries. The random canary values are unique to each slab cache. There's a separate value for active and inactive allocations to provide a quick way to check whether an allocation is active.
The canary value is checked both at free time and inside the __check_heap_object function used by HARDENED_USERCOPY which helps with detecting corruption earlier along with providing use-after-free detection there.
It would be nice if this feature was finally upstream. I'm not personally interested in spending my time dealing with linux kernel mailing lists and maintainers anymore, but I do want this to be upstream.
Performance overhead is incredibly low, especially when using it alongside zero-at-free. The canary is implemented by increasing the request size, meaning that when possible it avoids additional memory usage. For example, a 24 byte allocation is rounded to 32 bytes anyway so there's no additional memory usage. Many allocations do end up bumped into the next size class, so it does increase memory usage, but not as much as you might expect.
SLUB_DEBUG is not designed as a security feature and shouldn't actually be enabled in production on hardened systems. The redzone implementation fills spare padding space with a standard value and checks for it, then reports corruption when detected at free and attempts to recover. A security feature needs to guarantee a certain size of canary is present rather than only being opportunistic, should use a random value to prevent concealing a sequential overflow by matching the padding value and should use a leading zero to reliably contain string overflows like the Linux kernel stack canaries now do. Bug detection vs. security makes the implementation quite different very much like init on free / init on alloc vs. page/slab poisoning. It was accepted for that, and I think it should be accepted upstream for this too if someone is willing to deal with the hassle of trying to upstream it.
In linux-hardened, there's an implementation of random canaries that are 4 bytes on 32-bit and 8 bytes on 64-bit with a leading zero on 64-bit to reliably contain string function overflows both to prevent overflowing elsewhere and to protect leaking the canaries. The random canary values are unique to each slab cache. There's a separate value for active and inactive allocations to provide a quick way to check whether an allocation is active.
https://github.com/anthraxx/linux-hardened/commit/6649c22339d5b951dd95bd88ccc6e06f9d300d75.patch
The canary value is checked both at free time and inside the
__check_heap_object
function used by HARDENED_USERCOPY which helps with detecting corruption earlier along with providing use-after-free detection there.It would be nice if this feature was finally upstream. I'm not personally interested in spending my time dealing with linux kernel mailing lists and maintainers anymore, but I do want this to be upstream.
Performance overhead is incredibly low, especially when using it alongside zero-at-free. The canary is implemented by increasing the request size, meaning that when possible it avoids additional memory usage. For example, a 24 byte allocation is rounded to 32 bytes anyway so there's no additional memory usage. Many allocations do end up bumped into the next size class, so it does increase memory usage, but not as much as you might expect.