Skip to content

FixedBufferAllocator can integer overflow for obscene allocations #25371

@RetroDev256

Description

@RetroDev256

Zig Version

0.16.0-dev.387+4a344de65

Steps to Reproduce and Observed Behavior

This test:

test "avoid integer overflow for obscene allocations" {
    var buffer: [10]u8 = undefined;
    var fba: std.heap.FixedBufferAllocator = .init(&buffer);
    const gpa = fba.allocator();

    _ = try gpa.alloc(u8, 5);
    const problem = gpa.alloc(u8, std.math.maxInt(usize));
    try std.testing.expectError(error.OutOfMemory, problem);
}

Fails with the following:

retrodev@lime ~ $ zig test FixedBufferAllocator.zig 
thread 20050 panic: integer overflow
/home/retrodev/FixedBufferAllocator.zig:68:42: 0x10abb0f in alloc (FixedBufferAllocator.zig)
    const new_end_index = adjusted_index + n;
                                         ^
/home/retrodev/repos/Zig/.zig/0.16.0-dev.387+4a344de65/files/lib/std/mem/Allocator.zig:142:26: 0x107ca51 in allocBytesWithAlignment__anon_5024 (std.zig)
    return a.vtable.alloc(a.ptr, len, alignment, ret_addr);
                         ^
/home/retrodev/repos/Zig/.zig/0.16.0-dev.387+4a344de65/files/lib/std/mem/Allocator.zig:282:40: 0x104f149 in allocWithSizeAndAlignment__anon_2426 (std.zig)
    return self.allocBytesWithAlignment(alignment, byte_count, return_address);
                                       ^
/home/retrodev/repos/Zig/.zig/0.16.0-dev.387+4a344de65/files/lib/std/mem/Allocator.zig:270:89: 0x102afdd in alloc__anon_754 (std.zig)
    const ptr: [*]align(a.toByteUnits()) T = @ptrCast(try self.allocWithSizeAndAlignment(@sizeOf(T), a, n, return_address));
                                                                                        ^
/home/retrodev/FixedBufferAllocator.zig:238:30: 0x1135fbc in test.avoid integer overflow for obscene allocations (FixedBufferAllocator.zig)
    const problem = gpa.alloc(u8, std.math.maxInt(usize));
                             ^

The problem exists in both the "normal" allocator interface, and the threadSafeAllocator interface (via the threadSafeAlloc function). In optimized modes, this integer overflow could cause a false positive allocation.

Expected Behavior

I expect the test to pass. Both alloc functions should detect that the addition overflows, and return null (allocation failure).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions