-
-
Notifications
You must be signed in to change notification settings - Fork 95
Closed
Description
- I confirm this is a bug with Supabase, not with my own application.
- I confirm I have searched the Docs, GitHub Discussions, and Discord.
In ext/runtime/external_memory.rs, when an allocation exceeds the limit, the count is incremented but never rolled back on failure.
allocate and allocate_uninitialized
unsafe extern "C" fn allocate(allocator: &CustomAllocator, n: usize) -> *mut c_void {
allocator.count.fetch_add(n, Ordering::SeqCst); // count += n
let count_loaded = allocator.count.load(Ordering::SeqCst);
if count_loaded > allocator.max {
return std::ptr::null::<*mut [u8]>() as *mut c_void; // returns without rollback
}
// ...
}
reallocate
unsafe extern "C" fn reallocate(
allocator: &CustomAllocator,
prev: *mut c_void,
oldlen: usize,
newlen: usize,
) -> *mut c_void {
allocator
.count
.fetch_add(newlen.wrapping_sub(oldlen), Ordering::SeqCst); // count += (newlen - oldlen)
let count_loaded = allocator.count.load(Ordering::SeqCst);
if count_loaded > allocator.max {
return std::ptr::null::<*mut [u8]>() as *mut c_void; // returns without rollback
}
// ...
}
Impact
Attempt 1: allocate(100MB), limit=50MB → count=100MB → FAIL → count stays 100MB
Attempt 2: allocate(1KB) → count=100MB+1KB → FAIL (even though 1KB < 50MB)
All future allocations fail permanently, even small legitimate ones.
Fix
// allocate / allocate_uninitialized
if count_loaded > allocator.max {
allocator.count.fetch_sub(n, Ordering::SeqCst); // rollback
return std::ptr::null::<*mut [u8]>() as *mut c_void;
}
// reallocate
if count_loaded > allocator.max {
allocator.count.fetch_sub(newlen.wrapping_sub(oldlen), Ordering::SeqCst); // rollback
return std::ptr::null::<*mut [u8]>() as *mut c_void;
}
Happy to open a PR if you'd like.
kallebysantos
Metadata
Metadata
Assignees
Labels
No labels