Skip to content

[alloc] Add CheckedSlabBStackAllocator for secure slab allocation#7

Merged
williamwutq merged 14 commits into
masterfrom
allocators
Jun 1, 2026
Merged

[alloc] Add CheckedSlabBStackAllocator for secure slab allocation#7
williamwutq merged 14 commits into
masterfrom
allocators

Conversation

@williamwutq
Copy link
Copy Markdown
Owner

@williamwutq williamwutq commented Jun 1, 2026

CheckedSlabBStackAllocator

Description: Fixed-block slab allocator. All blocks in the arena are exactly block_size bytes (≥ 16) with 8 byte overhead per block. Provides fast allocation within in the size range and general (but slower) allocation for arbitrary sized blocks. Additionally provides double free protection and other corruption protection measures.

Important Feature: No
Type: Allocator
Magic Number: ALCK
Bulk: No
Tests: Needed
Feature Flags: alloc + set
Breaking change: No
New Types: CheckedSlabBStackAllocator
Rust Only: No
Fuzz: Yes
Safety Review: Needed: Crash Safety, Invariants

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new experimental allocator, CheckedSlabBStackAllocator, intended to provide crash-recoverable fixed-block slab allocation with runtime double-free detection on top of BStack storage.

Changes:

  • Added CheckedSlabBStackAllocator implementation with per-block overhead metadata and accompanying unit tests.
  • Exported the new allocator through alloc and the crate root when alloc + set features are enabled.
  • Extended existing allocator fuzz test suite coverage to include the new checked slab allocator.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/lib.rs Documents and re-exports CheckedSlabBStackAllocator under alloc + set.
src/alloc/mod.rs Adds the new checked_slab module and re-exports the allocator type.
src/alloc/checked_slab.rs Implements the new crash-recoverable checked slab allocator and unit tests.
src/alloc_fuzz_tests.rs Adds fuzz-suite instantiations for the checked slab allocator.
PLANNED.md Updates planned design notes wording around overhead-bit validation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/alloc/checked_slab.rs
Comment thread src/alloc/checked_slab.rs
Comment thread src/lib.rs
Comment thread PLANNED.md Outdated
@williamwutq
Copy link
Copy Markdown
Owner Author

Original PLANNED entry:

Adding CheckedSlabBStackAllocator for crash-recoverable slab allocation

Feature flag: alloc + set
Breaking change: No (additive; new type only)

Motivation

SlabBStackAllocator carries no per-block metadata, which means a crash leaves no way to distinguish live blocks from freed ones and offers no defence against double-free. CheckedSlabBStackAllocator adds an 8-byte overhead field to every block: zero when freed, non-zero when in use. This makes leaked blocks on crash recoverable by a linear scan and catches double-free at runtime before any list corruption occurs.

Design

Introduce CheckedSlabBStackAllocator in src/alloc/checked_slab.rs, implementing BStackSliceAllocator.

pub struct CheckedSlabBStackAllocator {
    stack: BStack,
    block_size: u64, // must be ≥ 16 (8 overhead + 8 minimum usable); never changes after init
}

The on-disk layout mirrors SlabBStackAllocator (same header structure, different magic, e.g. ALCK\x00\x01\x00\x00). Every block in the arena has an 8-byte overhead prefix:

[ overhead(8) | data ... ]

The overhead field encodes block state:

Value Meaning
0x0000_0000_0000_0000 Block is free. data[0..8] holds the next-free offset (little-endian u64, sentinel u64::MAX).
0x8NNN_NNNN_NNNN_NNNN Block is in use; NNN_NNNN_NNNN_NNNN is the allocation size in number of blocks; high bit is always 1.

Note: due to the fact that the minimum block size is 16 bytes, the maximum allocation size in number of blocks is 2^63 / 16 = 2^59 blocks, which means the 2nd-5th hex digits of the overhead are always zero. These bits may not be checked. They may be used in the future for additional metadata if needed.

block_size covers the full block including the 8-byte overhead. The slice returned to the caller covers data only, i.e. block_size − 8 bytes per slab block.

alloc(len): Compute the number of blocks needed as ceil((len + 8) / block_size). Pop the required count from the free list (verifying each overhead is zero; return an error on mismatch), write the overhead as (num_blocks | 0x8000_0000_0000_0000), zero data[0..8], and update the header. Fall back to tail extension if the free list is insufficient.

dealloc(slice): Read the overhead. If the high bit is clear (overhead is zero), the block is already free — return a double-free error without modifying the list. Otherwise do similar processing as dealloc of SlabBStackAllocator.

realloc: Same policy as SlabBStackAllocator with overhead updated on size changes.

Crash recovery: On open, scan the arena linearly. Any block whose overhead is non-zero and whose high bit is set is live; any block whose overhead is zero is free. A scan can reconstruct a valid free list from scratch if needed.

@williamwutq
Copy link
Copy Markdown
Owner Author

williamwutq commented Jun 1, 2026

The Feature Checklist

  1. API Design
    • Define new public types, functions, and traits.
    • API is consistent with the crate's design and follows Rust conventions.
    • All invariants are documented.
    • "Raw" accessors are provided and documented as such.
    • Methods do not panic unless justified; all panics are documented.
    • Invalid input is handled gracefully via Result or Option, not panics.
    • Methods that may compromise memory safety, whether that of BStack or the heap memory, are marked unsafe and documented.
    • Relevant traits are implemented (e.g., Debug, Clone, Copy, PartialEq, Read/Write).
    • Breaking changes are avoided where possible; if unavoidable, documented with migration guidance.
    • Forward compatibility and extensibility are considered.
    • If a plan exists, it addresses the Design section of the relevant issue, with all decisions resolved or documented.
    • Use the correct feature flags.
    • No additional dependencies.
  2. Implementation
    • All invariants are maintained.
    • No logical errors or overlooked edge cases.
    • No hidden assumptions.
    • Safe abstractions are preferred where practical.
    • Public APIs are re-exported in lib.rs and/or mod.rs as appropriate.
    • Implementation is reviewed.
    • If a plan exists, it addresses the Open Questions section of the relevant issue, with all questions resolved or documented.
    • No TODOs, FIXMEs, todo! macros, or unimplemented! macros remain in the code.
    • Interoperability with existing BStack APIs is considered and tested.
    • If not a Rust only feature, C version is implemented and tested.
  3. Safety
    • All unsafe code is justified, minimal, and well-documented.
    • Safety invariants are clearly stated in documentation for all unsafe items.
    • All methods are power-fail safe by default: interruption leaves BStack in a consistent state. Any exceptions or data-loss consequences (e.g., a block lost mid-allocation) are documented.
    • Thread safety is documented for all structs and methods; required synchronization is implemented.
    • In places where atomicity is relevant, document whether operations are atomic, and if not, what the implications are for concurrent usage.
  4. Optimisation
    • Implementation is optimised for time complexity, memory usage, and minimal BStack operations.
    • Trade-offs from any optimisations are documented.
    • Batching is considered.
    • Suggestions for further optimisations are added to PLANNED.md if not implemented now.
  5. Testing
    • Tests cover all functionality, edge cases, and error conditions.
    • Integration tests for overall behavior, if necessary.
    • New allocator implementations are added to alloc_fuzz_tests.rs and pass fuzz tests.
    • CI passes.
    • CodeQL passes without warnings.
  6. Documentation
    • All public items document their purpose, parameters, return values, and any panics or side effects.
    • cargo doc --all-features builds without warnings except unused manifest key.
    • Doc tests pass.
    • New feature flags have meaningful documentation. [N/A]
    • Changelog entry added.
    • For breaking changes, concise migration guidance provided in the changelog. [N/A]
    • README and lib.rs updated if the feature changes public-facing behavior or usage.
    • New files have a module-level doc comment describing their purpose.
    • Important new features have an example in examples/ showing realistic usage. [N/A]
    • New BStack usage patterns have a README section, lib.rs documentation, and an examples/ entry. [N/A]
    • Allocators and safety-sensitive methods include a markdown table. Example columns: name, atomicity, single-operation, and relevant notes.

Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
Comment thread c/test_checked_slab.c Dismissed
@williamwutq williamwutq marked this pull request as ready for review June 1, 2026 04:36
@williamwutq williamwutq requested a review from Copilot June 1, 2026 04:41
Comment thread c/test_checked_slab.c Dismissed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Comment thread src/alloc/checked_slab.rs
Comment thread src/alloc/checked_slab.rs
Comment thread src/alloc/checked_slab.rs
Comment thread c/bstack_alloc.c Outdated
Comment thread c/bstack_alloc.c
Comment thread c/bstack_alloc.c
Comment thread c/bstack_alloc.c
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@williamwutq
Copy link
Copy Markdown
Owner Author

@williamwutq Review

Copy link
Copy Markdown
Owner Author

@williamwutq williamwutq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@williamwutq williamwutq merged commit b20112b into master Jun 1, 2026
19 checks passed
@williamwutq williamwutq deleted the allocators branch June 1, 2026 18:29
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

Successfully merging this pull request may close these issues.

3 participants