From: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> Date: Wed, 5 Apr 2023 21:26:47 +0900 > On 3/15/2023 6:54 PM, GONG, Ruiqi wrote: >> When exploiting memory vulnerabilities, "heap spraying" is a common >> technique targeting those related to dynamic memory allocation (i.e. the >> "heap"), and it plays an important role in a successful exploitation. >> Basically, it is to overwrite the memory area of vulnerable object by >> triggering allocation in other subsystems or modules and therefore >> getting a reference to the targeted memory location. It's usable on >> various types of vulnerablity including use after free (UAF), heap out- >> of-bound write and etc. >> >> There are (at least) two reasons why the heap can be sprayed: 1) generic >> slab caches are shared among different subsystems and modules, and >> 2) dedicated slab caches could be merged with the generic ones. >> Currently these two factors cannot be prevented at a low cost: the first >> one is a widely used memory allocation mechanism, and shutting down slab >> merging completely via `slub_nomerge` would be overkill. >> >> To efficiently prevent heap spraying, we propose the following approach: >> to create multiple copies of generic slab caches that will never be >> merged, and random one of them will be used at allocation. The random >> selection is based on the location of code that calls `kmalloc()`, which >> means it is static at runtime (rather than dynamically determined at >> each time of allocation, which could be bypassed by repeatedly spraying >> in brute force). In this way, the vulnerable object and memory allocated >> in other subsystems and modules will (most probably) be on different >> slab caches, which prevents the object from being sprayed. >> >> Signed-off-by: GONG, Ruiqi <gongruiqi1@xxxxxxxxxx> >> --- > > I'm not yet sure if this feature is appropriate for mainline kernel. > > I have few questions: > > 1) What is cost of this configuration, in terms of memory overhead, or > execution time? > > > 2) The actual cache depends on caller which is static at build time, not > runtime. > > What about using (caller ^ (some subsystem-wide random sequence)), > > which is static at runtime? Why can't we just do random_get_u32_below(CONFIG_RANDOM_KMALLOC_CACHES_NR) ? It's fast enough according to Jason... `_RET_IP_ % nr` doesn't sound "secure" to me. It really is a compile-time constant, which can be calculated (or not?) manually. Even if it wasn't, `% nr` doesn't sound good, there should be at least hash_32(). Thanks, Olek