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

Generic Fail-able, Pool and Tag Aware Allocators #5

Open
jxy-s opened this issue Sep 22, 2023 · 2 comments
Open

Generic Fail-able, Pool and Tag Aware Allocators #5

jxy-s opened this issue Sep 22, 2023 · 2 comments

Comments

@jxy-s
Copy link

jxy-s commented Sep 22, 2023

Development in the Windows Kernel requires allocations from different pools and the capability to tag allocations is an invaluable tool for debugging/triage.

Today this repository looks to recommend a global allocator and one that allocates exclusively from non-paged pool with a hard-coded pool tag.

unsafe impl GlobalAlloc for WDKAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let ptr = ExAllocatePool2(POOL_FLAG_NON_PAGED, layout.size() as SIZE_T, *RUST_TAG);
assert!(!ptr.is_null(), "wdk-alloc failed to allocate memory.");
ptr.cast()
}
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
ExFreePool(ptr.cast());
}
}

Rust crates for the Windows Kernel probably shouldn't provide a global kernel allocator. Else everyone using these crates may subtly end up allocating memory using identical tags. This will make debugging and triage a nightmare in the long term. Additionally I'll note, the non-paged pools are far more limited resource that the paged pools. I recognize that the safer option when implementing a global allocator is to force it into non-paged memory, since not doing so has the potential to introduce other issues. However resource exhaustion is far more likely when forcing all allocations into non-paged pools.

For Rust to be a first-class citizen in the Windows Kernel. The language must support generic fail-able allocators. And the crates for the Windows Kernel should expose and support appropriate allocators that are capable of specifying pool types and tags.

@jxy-s jxy-s changed the title Generic Fail-able (and Taggable) Allocators Generic Fail-able, Pool and Tag Aware Allocators Sep 22, 2023
@wmmc88
Copy link
Collaborator

wmmc88 commented Sep 25, 2023

Users of these crates are free to consume them without the alloc feature, and define their own allocators with their own tags and pool.

Rust requires a global allocator to be defined in order to use the types in the alloc module in the standard library(ex. alloc::vec). But this doesn't force all allocations to use that allocator, the user is still free to allocate themselves via the rust binding to ExAllocatePool2.

Ideally, we would like to support alloc types with different allocator "settings"(ie. pool and tag) each time, but this is currently not something that is supported in stable rust. In unstable rust, there are currently two approaches to provide alloc types with custom allocators: the allocator-api proposal (which some libraries implement on stable via allocator_api2), and a Storage-backed allocator proposal.

@jxy-s
Copy link
Author

jxy-s commented Sep 25, 2023

Rust requires a global allocator to be defined in order to use the types in the alloc module in the standard library(ex. alloc::vec). But this doesn't force all allocations to use that allocator, the user is still free to allocate themselves via the rust binding to ExAllocatePool2.

I think this ties back to #6 and #6 (comment). alloc::vec will abort the "program" if it can't allocate. I think that's an unacceptable outcome for the kernel. If the kernel can't allocate memory for some request it shouldn't bugcheck.

Users of these crates are free to consume them without the alloc feature, and define their own allocators with their own tags and pool.

As was said elegantly in the comment on the other issue, "I think it would be beneficial to consider options with how to make this a bit safer for developers to avoid some mishaps that are likely going to be very easy to make (e.g. accidentally using the wrong memory allocator)."

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

No branches or pull requests

2 participants