authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-06-02 01:55:16+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:58-07:00
loge0179640d54f4a61aa7522ac8529d36769fb9c08
tree3bcd901567fea1e9206e1323411a65b22cfcfeed
parente8bcdca044603fb5ea93fc94028dfd8bdd22fcf3

Sema: intern values of mutable decls after analysis

This is necessary with the upcoming removal of Decl.value_arena to prevent UAF of these values.

2 files changed, 74 insertions(+), 1 deletions(-)

src/Module.zig+24
......@@ -4424,6 +4424,9 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
44244424 defer sema_arena.deinit();
44254425 const sema_arena_allocator = sema_arena.allocator();
44264426
4427 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
4428 defer comptime_mutable_decls.deinit();
4429
44274430 var sema: Sema = .{
44284431 .mod = mod,
44294432 .gpa = gpa,
......@@ -4437,6 +4440,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
44374440 .fn_ret_ty = Type.void,
44384441 .owner_func = null,
44394442 .owner_func_index = .none,
4443 .comptime_mutable_decls = &comptime_mutable_decls,
44404444 };
44414445 defer sema.deinit();
44424446
......@@ -4445,6 +4449,10 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
44454449
44464450 if (sema.analyzeStructDecl(new_decl, main_struct_inst, struct_index)) |_| {
44474451 try wip_captures.finalize();
4452 for (comptime_mutable_decls.items) |decl_index| {
4453 const decl = mod.declPtr(decl_index);
4454 try decl.intern(mod);
4455 }
44484456 new_decl.analysis = .complete;
44494457 } else |err| switch (err) {
44504458 error.OutOfMemory => return error.OutOfMemory,
......@@ -4522,6 +4530,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45224530 defer analysis_arena.deinit();
45234531 const analysis_arena_allocator = analysis_arena.allocator();
45244532
4533 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
4534 defer comptime_mutable_decls.deinit();
4535
45254536 var sema: Sema = .{
45264537 .mod = mod,
45274538 .gpa = gpa,
......@@ -4535,6 +4546,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45354546 .fn_ret_ty = Type.void,
45364547 .owner_func = null,
45374548 .owner_func_index = .none,
4549 .comptime_mutable_decls = &comptime_mutable_decls,
45384550 };
45394551 defer sema.deinit();
45404552
......@@ -4577,6 +4589,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45774589 const body = zir.extra[extra.end..][0..extra.data.body_len];
45784590 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
45794591 try wip_captures.finalize();
4592 for (comptime_mutable_decls.items) |ct_decl_index| {
4593 const ct_decl = mod.declPtr(ct_decl_index);
4594 try ct_decl.intern(mod);
4595 }
45804596 const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 };
45814597 const section_src: LazySrcLoc = .{ .node_offset_var_decl_section = 0 };
45824598 const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };
......@@ -5486,6 +5502,9 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
54865502 const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
54875503 defer decl.value_arena.?.release(&decl_arena);
54885504
5505 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
5506 defer comptime_mutable_decls.deinit();
5507
54895508 const fn_ty = decl.ty;
54905509 const fn_ty_info = mod.typeToFunc(fn_ty).?;
54915510
......@@ -5503,6 +5522,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
55035522 .owner_func = func,
55045523 .owner_func_index = func_index.toOptional(),
55055524 .branch_quota = @max(func.branch_quota, Sema.default_branch_quota),
5525 .comptime_mutable_decls = &comptime_mutable_decls,
55065526 };
55075527 defer sema.deinit();
55085528
......@@ -5642,6 +5662,10 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
56425662 }
56435663
56445664 try wip_captures.finalize();
5665 for (comptime_mutable_decls.items) |ct_decl_index| {
5666 const ct_decl = mod.declPtr(ct_decl_index);
5667 try ct_decl.intern(mod);
5668 }
56455669
56465670 // Copy the block into place and mark that as the main block.
56475671 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
src/Sema.zig+50-1
......@@ -92,6 +92,14 @@ no_partial_func_ty: bool = false,
9292/// here so the values can be dropped without any cleanup.
9393unresolved_inferred_allocs: std.AutoHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{},
9494
95/// Indices of comptime-mutable decls created by this Sema. These decls' values
96/// should be interned after analysis completes, as they may refer to memory in
97/// the Sema arena.
98/// TODO: this is a workaround for memory bugs triggered by the removal of
99/// Decl.value_arena. A better solution needs to be found. Probably this will
100/// involve transitioning comptime-mutable memory away from using Decls at all.
101comptime_mutable_decls: *std.ArrayList(Decl.Index),
102
95103const std = @import("std");
96104const math = std.math;
97105const mem = std.mem;
......@@ -2545,6 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
25452553 },
25462554 });
25472555 try sema.maybeQueueFuncBodyAnalysis(decl_index);
2556 try sema.comptime_mutable_decls.append(decl_index);
25482557 return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{
25492558 .ty = ptr_ty.toIntern(),
25502559 .addr = .{ .mut_decl = .{
......@@ -7761,6 +7770,7 @@ fn resolveGenericInstantiationType(
77617770 .is_generic_instantiation = true,
77627771 .branch_quota = sema.branch_quota,
77637772 .branch_count = sema.branch_count,
7773 .comptime_mutable_decls = sema.comptime_mutable_decls,
77647774 };
77657775 defer child_sema.deinit();
77667776
......@@ -31863,7 +31873,24 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3186331873 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3186431874 defer analysis_arena.deinit();
3186531875
31866 var sema: Sema = .{ .mod = mod, .gpa = gpa, .arena = analysis_arena.allocator(), .perm_arena = decl_arena_allocator, .code = zir, .owner_decl = decl, .owner_decl_index = decl_index, .func = null, .func_index = .none, .fn_ret_ty = Type.void, .owner_func = null, .owner_func_index = .none };
31876 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
31877 defer comptime_mutable_decls.deinit();
31878
31879 var sema: Sema = .{
31880 .mod = mod,
31881 .gpa = gpa,
31882 .arena = analysis_arena.allocator(),
31883 .perm_arena = decl_arena_allocator,
31884 .code = zir,
31885 .owner_decl = decl,
31886 .owner_decl_index = decl_index,
31887 .func = null,
31888 .func_index = .none,
31889 .fn_ret_ty = Type.void,
31890 .owner_func = null,
31891 .owner_func_index = .none,
31892 .comptime_mutable_decls = &comptime_mutable_decls,
31893 };
3186731894 defer sema.deinit();
3186831895
3186931896 var wip_captures = try WipCaptureScope.init(gpa, decl.src_scope);
......@@ -31899,6 +31926,10 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3189931926 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
3190031927 struct_obj.backing_int_ty = backing_int_ty;
3190131928 try wip_captures.finalize();
31929 for (comptime_mutable_decls.items) |ct_decl_index| {
31930 const ct_decl = mod.declPtr(ct_decl_index);
31931 try ct_decl.intern(mod);
31932 }
3190231933 } else {
3190331934 if (fields_bit_sum > std.math.maxInt(u16)) {
3190431935 var sema: Sema = .{
......@@ -31914,6 +31945,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3191431945 .fn_ret_ty = Type.void,
3191531946 .owner_func = null,
3191631947 .owner_func_index = .none,
31948 .comptime_mutable_decls = undefined,
3191731949 };
3191831950 defer sema.deinit();
3191931951
......@@ -32603,6 +32635,9 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3260332635 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3260432636 defer analysis_arena.deinit();
3260532637
32638 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
32639 defer comptime_mutable_decls.deinit();
32640
3260632641 var sema: Sema = .{
3260732642 .mod = mod,
3260832643 .gpa = gpa,
......@@ -32616,6 +32651,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3261632651 .fn_ret_ty = Type.void,
3261732652 .owner_func = null,
3261832653 .owner_func_index = .none,
32654 .comptime_mutable_decls = &comptime_mutable_decls,
3261932655 };
3262032656 defer sema.deinit();
3262132657
......@@ -32886,6 +32922,10 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3288632922 }
3288732923 }
3288832924 try wip_captures.finalize();
32925 for (comptime_mutable_decls.items) |ct_decl_index| {
32926 const ct_decl = mod.declPtr(ct_decl_index);
32927 try ct_decl.intern(mod);
32928 }
3288932929
3289032930 struct_obj.have_field_inits = true;
3289132931}
......@@ -32945,6 +32985,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3294532985 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3294632986 defer analysis_arena.deinit();
3294732987
32988 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
32989 defer comptime_mutable_decls.deinit();
32990
3294832991 var sema: Sema = .{
3294932992 .mod = mod,
3295032993 .gpa = gpa,
......@@ -32958,6 +33001,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3295833001 .fn_ret_ty = Type.void,
3295933002 .owner_func = null,
3296033003 .owner_func_index = .none,
33004 .comptime_mutable_decls = &comptime_mutable_decls,
3296133005 };
3296233006 defer sema.deinit();
3296333007
......@@ -32984,6 +33028,10 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3298433028 }
3298533029
3298633030 try wip_captures.finalize();
33031 for (comptime_mutable_decls.items) |ct_decl_index| {
33032 const ct_decl = mod.declPtr(ct_decl_index);
33033 try ct_decl.intern(mod);
33034 }
3298733035
3298833036 try union_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
3298933037
......@@ -33821,6 +33869,7 @@ fn analyzeComptimeAlloc(
3382133869 const decl = sema.mod.declPtr(decl_index);
3382233870 decl.@"align" = alignment;
3382333871
33872 try sema.comptime_mutable_decls.append(decl_index);
3382433873 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
3382533874 return sema.addConstant(ptr_type, (try sema.mod.intern(.{ .ptr = .{
3382633875 .ty = ptr_type.toIntern(),