Skip to content

Commit b1b641a

Browse files
committed
fix: heap-allocate queue_family_indices in GrowableBufferArena to prevent use-after-free
1 parent dfb64d1 commit b1b641a

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

src/client/renderer/buffer/GrowableBufferArena.zig

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,21 @@ pub const GrowableBufferArena = struct {
100100
config: GrowableBufferConfig,
101101
io: Io,
102102
) !Self {
103+
// Heap-allocate a copy of queue_family_indices so it survives beyond the caller's
104+
// stack frame. The original slice may point to a stack temporary (e.g. &[_]u32{...}).
105+
// asyncAllocateArena reads this config on a background thread, so we need stable storage.
106+
var owned_config = config;
107+
const owned_indices: ?[]const u32 = if (config.queue_family_indices) |indices| blk: {
108+
const duped = try allocator.dupe(u32, indices);
109+
break :blk duped;
110+
} else null;
111+
owned_config.queue_family_indices = owned_indices;
112+
103113
var self = Self{
104114
.arenas = .{},
105115
.device = device,
106116
.physical_device = physical_device,
107-
.config = config,
117+
.config = owned_config,
108118
.allocator = allocator,
109119
.io = io,
110120
};
@@ -204,6 +214,11 @@ pub const GrowableBufferArena = struct {
204214
}
205215
self.arenas.deinit(self.allocator);
206216

217+
// Free heap-allocated queue family indices
218+
if (self.config.queue_family_indices) |indices| {
219+
self.allocator.free(@constCast(indices));
220+
}
221+
207222
logger.info("GrowableBufferArena destroyed: {} allocations, {} frees, {} expansions", .{
208223
self.total_allocations,
209224
self.total_frees,

0 commit comments

Comments
 (0)