Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate slab allocations by type #189

Open
kees opened this issue May 5, 2022 · 5 comments
Open

Separate slab allocations by type #189

kees opened this issue May 5, 2022 · 5 comments

Comments

@kees
Copy link

kees commented May 5, 2022

A common UAF involves implicit type confusion by reusing allocations of memory that get allocated to a different struct of a similar size. It would be nice to provide an implicit kmem_cache_create()-like system for each distinct allocation type, but this requires introspection into the type being allocated.

This would also get rid of redundant sizeof(*ptr) arguments. For example:

rc = kmalloc(&var, GFP_KERNEL);

Dynamically sized allocations (flexible array structs) could still be type-separated, but would have a kmalloc-like bucket system.

To avoid needing to rewrite all callers everywhere, it might also be possible to grow a compiler extension to allow for lvalue type introspection, like __builtin_lvalue_type():

#define kmalloc(var, GFP_KERNEL) __kmalloc(var, sizeof(*__builtin_lvalue_type()))

Alternatively, allocations could be separated by caller location, but it's possible this may be too granular. It would be nice to compare performance characteristics.

It's important to address cross-allocator attacks as well. Such a "no virtual address reuse across types" solution has been proposed to cover this part of the problem too.

@kees
Copy link
Author

kees commented May 7, 2022

@nickdesaulniers
Copy link
Member

@nickdesaulniers
Copy link
Member

To avoid needing to rewrite all callers everywhere, it might also be possible to grow a compiler extension to allow for lvalue type introspection, like __builtin_lvalue_type():
I'd still prefer avoiding rewriting all the existing kmalloc calls in Linux. :)

The identifier being assigned to can be referenced in the RHS of an assignment expression:

// type specific slab
void* kmalloc_int(size_t size, int flags);

#define kmalloc2(size, flags, type) _Generic((*type), int: kmalloc_int(size, flags))

int *foo (void) {
    int *bar = kmalloc2(sizeof(*bar), GFP_KERNEL, bar);
    return bar;
}

@kees
Copy link
Author

kees commented Feb 22, 2024

We should be able to use the proposed allocation profiling infrastructure to accomplish per-call-site caches:
https://lore.kernel.org/all/202402211449.401382D2AF@keescook/

@kees
Copy link
Author

kees commented Aug 23, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants