Skip to content

Instantly share code, notes, and snippets.

@y21
Last active February 19, 2022 21:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y21/64d8f2ebb9635b3e4fa95ca0a87bc497 to your computer and use it in GitHub Desktop.
Save y21/64d8f2ebb9635b3e4fa95ca0a87bc497 to your computer and use it in GitHub Desktop.
Boa
use std::{
alloc::{GlobalAlloc, Layout},
ptr::{self},
};
use boa::JsString;
struct BadAllocator<A: GlobalAlloc>(A);
// Implementing the GlobalAlloc trait is unsafe by nature because one could "just" return any invalid pointer
// and cause memory unsafety that way, but all this is doing is delegate to the underlying allocator
// (and returning null for the JsString::new allocation, which is totally valid to do)
// This could have been exposed by a crate with a safe interface
unsafe impl<A: GlobalAlloc> GlobalAlloc for BadAllocator<A> {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
// I chose a reasonably large size so we can uniquely identify the JsString allocation
// in the real world, we can't assume anything about the system allocator and it could return null at any time
if layout.size() >= 5000 {
// The first allocation happens in "a".repeat(5000), so I'm using a counter to skip the first one
// (Horrible idea but it "works" for this example)
static mut ALLOCATIONS: usize = 0;
if ALLOCATIONS == 1 {
// If this is the second allocation, return null to indicate an allocation error
return ptr::null_mut();
}
ALLOCATIONS += 1;
}
// Otherwise just delegate to the normal allocator
self.0.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
// Nothing special to do here
self.0.dealloc(ptr, layout)
}
}
// Wrap the system allocator
#[global_allocator]
static ALLOC: BadAllocator<std::alloc::System> = BadAllocator(std::alloc::System);
fn main() {
// some special number that's "unlikely to be used somewhere else" in unrelated places
let _ = JsString::new(&"a".repeat(5000));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment