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 {...@@ -272,6 +272,8 @@ pub const Function = struct {
272 /// variable declarations at the top of a function, sorted descending by272 /// variable declarations at the top of a function, sorted descending by
273 /// type alignment.273 /// type alignment.
274 allocs: std.AutoArrayHashMapUnmanaged(LocalIndex, void) = .{},274 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
276 fn tyHashCtx(f: Function) Type.HashContext32 {278 fn tyHashCtx(f: Function) Type.HashContext32 {
277 return .{ .mod = f.object.dg.module };279 return .{ .mod = f.object.dg.module };
...@@ -314,7 +316,7 @@ pub const Function = struct {...@@ -314,7 +316,7 @@ pub const Function = struct {
314 .ty = ty,316 .ty = ty,
315 .alignment = alignment,317 .alignment = alignment,
316 });318 });
317 return .{ .local = @intCast(LocalIndex, f.locals.items.len - 1) };319 return CValue{ .local = @intCast(LocalIndex, f.locals.items.len - 1) };
318 }320 }
319321
320 fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue {322 fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue {
...@@ -420,6 +422,7 @@ pub const Function = struct {...@@ -420,6 +422,7 @@ pub const Function = struct {
420 }422 }
421 f.object.dg.typedefs.deinit();423 f.object.dg.typedefs.deinit();
422 f.object.dg.fwd_decl.deinit();424 f.object.dg.fwd_decl.deinit();
425 f.arena.deinit();
423 }426 }
424};427};
425428
...@@ -3228,8 +3231,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {...@@ -3228,8 +3231,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3228 var deref = is_ptr;3231 var deref = is_ptr;
3229 const operand = try f.resolveInst(un_op);3232 const operand = try f.resolveInst(un_op);
3230 try reap(f, inst, &.{un_op});3233 try reap(f, inst, &.{un_op});
3231 const ret_val = if (lowersToArray(ret_ty, target)) ret_val: {3234 const is_array = lowersToArray(ret_ty, target);
3232 const array_local = try f.allocLocal(inst, lowered_ret_ty);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()));
3233 try writer.writeAll("memcpy(");3237 try writer.writeAll("memcpy(");
3234 try f.writeCValueMember(writer, array_local, .{ .field = 0 });3238 try f.writeCValueMember(writer, array_local, .{ .field = 0 });
3235 try writer.writeAll(", ");3239 try writer.writeAll(", ");
...@@ -3250,6 +3254,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {...@@ -3250,6 +3254,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3250 else3254 else
3251 try f.writeCValue(writer, ret_val, .Other);3255 try f.writeCValue(writer, ret_val, .Other);
3252 try writer.writeAll(";\n");3256 try writer.writeAll(";\n");
3257 if (is_array) {
3258 try freeLocal(f, inst, ret_val.local, 0);
3259 }
3253 } else {3260 } else {
3254 try reap(f, inst, &.{un_op});3261 try reap(f, inst, &.{un_op});
3255 if (f.object.dg.decl.ty.fnCallingConvention() != .Naked) {3262 if (f.object.dg.decl.ty.fnCallingConvention() != .Naked) {
...@@ -3884,7 +3891,7 @@ fn airCall(...@@ -3884,7 +3891,7 @@ fn airCall(
3884 try writer.writeByte(')');3891 try writer.writeByte(')');
3885 break :r .none;3892 break :r .none;
3886 } else r: {3893 } 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()));
3888 try f.writeCValue(writer, local, .Other);3895 try f.writeCValue(writer, local, .Other);
3889 try writer.writeAll(" = ");3896 try writer.writeAll(" = ");
3890 break :r local;3897 break :r local;
...@@ -5110,7 +5117,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5110,7 +5117,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5110 };5117 };
5111 const field_int_ty = Type.initPayload(&field_int_pl.base);5118 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()));
5114 try f.writeCValue(writer, temp_local, .Other);5121 try f.writeCValue(writer, temp_local, .Other);
5115 try writer.writeAll(" = zig_wrap_");5122 try writer.writeAll(" = zig_wrap_");
5116 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);5123 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...@@ -133,6 +133,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
133 .code = code.toManaged(module.gpa),133 .code = code.toManaged(module.gpa),
134 .indent_writer = undefined, // set later so we can get a pointer to object.code134 .indent_writer = undefined, // set later so we can get a pointer to object.code
135 },135 },
136 .arena = std.heap.ArenaAllocator.init(module.gpa),
136 };137 };
137138
138 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };139 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };