authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-03 02:59:02-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-04 15:57:40-07:00
logdb1819e8ed02d3bb230b82f875b45fe7a6274c49
treeddc47479d455048dfa2dfd9c52833fcb5abcb258
parent7bd63a602a433044f321534117570b1da338e946

CBE: fix use-after-free of Type keys in free_locals map


2 files changed, 13 insertions(+), 5 deletions(-)

src/codegen/c.zig+12-5
......@@ -272,6 +272,8 @@ pub const Function = struct {
272272 /// variable declarations at the top of a function, sorted descending by
273273 /// type alignment.
274274 allocs: std.AutoArrayHashMapUnmanaged(LocalIndex, void) = .{},
275 /// Needed for memory used by Type objects used as keys in free_locals.
276 arena: std.heap.ArenaAllocator,
275277
276278 fn tyHashCtx(f: Function) Type.HashContext32 {
277279 return .{ .mod = f.object.dg.module };
......@@ -314,7 +316,7 @@ pub const Function = struct {
314316 .ty = ty,
315317 .alignment = alignment,
316318 });
317 return .{ .local = @intCast(LocalIndex, f.locals.items.len - 1) };
319 return CValue{ .local = @intCast(LocalIndex, f.locals.items.len - 1) };
318320 }
319321
320322 fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue {
......@@ -420,6 +422,7 @@ pub const Function = struct {
420422 }
421423 f.object.dg.typedefs.deinit();
422424 f.object.dg.fwd_decl.deinit();
425 f.arena.deinit();
423426 }
424427};
425428
......@@ -3228,8 +3231,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
32283231 var deref = is_ptr;
32293232 const operand = try f.resolveInst(un_op);
32303233 try reap(f, inst, &.{un_op});
3231 const ret_val = if (lowersToArray(ret_ty, target)) ret_val: {
3232 const array_local = try f.allocLocal(inst, lowered_ret_ty);
3234 const is_array = lowersToArray(ret_ty, target);
3235 const ret_val = if (is_array) ret_val: {
3236 const array_local = try f.allocLocal(inst, try lowered_ret_ty.copy(f.arena.allocator()));
32333237 try writer.writeAll("memcpy(");
32343238 try f.writeCValueMember(writer, array_local, .{ .field = 0 });
32353239 try writer.writeAll(", ");
......@@ -3250,6 +3254,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
32503254 else
32513255 try f.writeCValue(writer, ret_val, .Other);
32523256 try writer.writeAll(";\n");
3257 if (is_array) {
3258 try freeLocal(f, inst, ret_val.local, 0);
3259 }
32533260 } else {
32543261 try reap(f, inst, &.{un_op});
32553262 if (f.object.dg.decl.ty.fnCallingConvention() != .Naked) {
......@@ -3884,7 +3891,7 @@ fn airCall(
38843891 try writer.writeByte(')');
38853892 break :r .none;
38863893 } else r: {
3887 const local = try f.allocLocal(inst, lowered_ret_ty);
3894 const local = try f.allocLocal(inst, try lowered_ret_ty.copy(f.arena.allocator()));
38883895 try f.writeCValue(writer, local, .Other);
38893896 try writer.writeAll(" = ");
38903897 break :r local;
......@@ -5110,7 +5117,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
51105117 };
51115118 const field_int_ty = Type.initPayload(&field_int_pl.base);
51125119
5113 const temp_local = try f.allocLocal(inst, field_int_ty);
5120 const temp_local = try f.allocLocal(inst, try field_int_ty.copy(f.arena.allocator()));
51145121 try f.writeCValue(writer, temp_local, .Other);
51155122 try writer.writeAll(" = zig_wrap_");
51165123 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);
src/link/C.zig+1
......@@ -133,6 +133,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
133133 .code = code.toManaged(module.gpa),
134134 .indent_writer = undefined, // set later so we can get a pointer to object.code
135135 },
136 .arena = std.heap.ArenaAllocator.init(module.gpa),
136137 };
137138
138139 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };