authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-23 03:38:51+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-23 11:32:37+01:00
loga7282d09101b4339fc71d5ea78927c598aee0f52
tree5bf8431bd154460e683ac961614ce28c9d19d50e
parentff7ca4b70fc411a9e1e3ba94a06333601a229e6e

WasmAllocator: fix safety panic during OOM


1 files changed, 8 insertions(+), 10 deletions(-)

lib/std/heap/WasmAllocator.zig+8-10
...@@ -55,7 +55,7 @@ fn alloc(ctx: *anyopaque, len: usize, log2_align: u8, return_address: usize) ?[*...@@ -55,7 +55,7 @@ fn alloc(ctx: *anyopaque, len: usize, log2_align: u8, return_address: usize) ?[*
55 const addr = a: {55 const addr = a: {
56 const top_free_ptr = frees[class];56 const top_free_ptr = frees[class];
57 if (top_free_ptr != 0) {57 if (top_free_ptr != 0) {
58 const node = @as(*usize, @ptrFromInt(top_free_ptr + (slot_size - @sizeOf(usize))));58 const node: *usize = @ptrFromInt(top_free_ptr + (slot_size - @sizeOf(usize)));
59 frees[class] = node.*;59 frees[class] = node.*;
60 break :a top_free_ptr;60 break :a top_free_ptr;
61 }61 }
...@@ -74,11 +74,10 @@ fn alloc(ctx: *anyopaque, len: usize, log2_align: u8, return_address: usize) ?[*...@@ -74,11 +74,10 @@ fn alloc(ctx: *anyopaque, len: usize, log2_align: u8, return_address: usize) ?[*
74 break :a next_addr;74 break :a next_addr;
75 }75 }
76 };76 };
77 return @as([*]u8, @ptrFromInt(addr));77 return @ptrFromInt(addr);
78 }78 }
79 const bigpages_needed = bigPagesNeeded(actual_len);79 const bigpages_needed = bigPagesNeeded(actual_len);
80 const addr = allocBigPages(bigpages_needed);80 return @ptrFromInt(allocBigPages(bigpages_needed));
81 return @as([*]u8, @ptrFromInt(addr));
82}81}
8382
84fn resize(83fn resize(
...@@ -123,14 +122,14 @@ fn free(...@@ -123,14 +122,14 @@ fn free(
123 const class = math.log2(slot_size) - min_class;122 const class = math.log2(slot_size) - min_class;
124 const addr = @intFromPtr(buf.ptr);123 const addr = @intFromPtr(buf.ptr);
125 if (class < size_class_count) {124 if (class < size_class_count) {
126 const node = @as(*usize, @ptrFromInt(addr + (slot_size - @sizeOf(usize))));125 const node: *usize = @ptrFromInt(addr + (slot_size - @sizeOf(usize)));
127 node.* = frees[class];126 node.* = frees[class];
128 frees[class] = addr;127 frees[class] = addr;
129 } else {128 } else {
130 const bigpages_needed = bigPagesNeeded(actual_len);129 const bigpages_needed = bigPagesNeeded(actual_len);
131 const pow2_pages = math.ceilPowerOfTwoAssert(usize, bigpages_needed);130 const pow2_pages = math.ceilPowerOfTwoAssert(usize, bigpages_needed);
132 const big_slot_size_bytes = pow2_pages * bigpage_size;131 const big_slot_size_bytes = pow2_pages * bigpage_size;
133 const node = @as(*usize, @ptrFromInt(addr + (big_slot_size_bytes - @sizeOf(usize))));132 const node: *usize = @ptrFromInt(addr + (big_slot_size_bytes - @sizeOf(usize)));
134 const big_class = math.log2(pow2_pages);133 const big_class = math.log2(pow2_pages);
135 node.* = big_frees[big_class];134 node.* = big_frees[big_class];
136 big_frees[big_class] = addr;135 big_frees[big_class] = addr;
...@@ -148,15 +147,14 @@ fn allocBigPages(n: usize) usize {...@@ -148,15 +147,14 @@ fn allocBigPages(n: usize) usize {
148147
149 const top_free_ptr = big_frees[class];148 const top_free_ptr = big_frees[class];
150 if (top_free_ptr != 0) {149 if (top_free_ptr != 0) {
151 const node = @as(*usize, @ptrFromInt(top_free_ptr + (slot_size_bytes - @sizeOf(usize))));150 const node: *usize = @ptrFromInt(top_free_ptr + (slot_size_bytes - @sizeOf(usize)));
152 big_frees[class] = node.*;151 big_frees[class] = node.*;
153 return top_free_ptr;152 return top_free_ptr;
154 }153 }
155154
156 const page_index = @wasmMemoryGrow(0, pow2_pages * pages_per_bigpage);155 const page_index = @wasmMemoryGrow(0, pow2_pages * pages_per_bigpage);
157 if (page_index <= 0) return 0;156 if (page_index == -1) return 0;
158 const addr = @as(u32, @intCast(page_index)) * wasm.page_size;157 return @as(usize, @intCast(page_index)) * wasm.page_size;
159 return addr;
160}158}
161159
162const test_ally = Allocator{160const test_ally = Allocator{