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 {...@@ -4424,6 +4424,9 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4424 defer sema_arena.deinit();4424 defer sema_arena.deinit();
4425 const sema_arena_allocator = sema_arena.allocator();4425 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
4427 var sema: Sema = .{4430 var sema: Sema = .{
4428 .mod = mod,4431 .mod = mod,
4429 .gpa = gpa,4432 .gpa = gpa,
...@@ -4437,6 +4440,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -4437,6 +4440,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4437 .fn_ret_ty = Type.void,4440 .fn_ret_ty = Type.void,
4438 .owner_func = null,4441 .owner_func = null,
4439 .owner_func_index = .none,4442 .owner_func_index = .none,
4443 .comptime_mutable_decls = &comptime_mutable_decls,
4440 };4444 };
4441 defer sema.deinit();4445 defer sema.deinit();
44424446
...@@ -4445,6 +4449,10 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -4445,6 +4449,10 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
44454449
4446 if (sema.analyzeStructDecl(new_decl, main_struct_inst, struct_index)) |_| {4450 if (sema.analyzeStructDecl(new_decl, main_struct_inst, struct_index)) |_| {
4447 try wip_captures.finalize();4451 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 }
4448 new_decl.analysis = .complete;4456 new_decl.analysis = .complete;
4449 } else |err| switch (err) {4457 } else |err| switch (err) {
4450 error.OutOfMemory => return error.OutOfMemory,4458 error.OutOfMemory => return error.OutOfMemory,
...@@ -4522,6 +4530,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4522,6 +4530,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4522 defer analysis_arena.deinit();4530 defer analysis_arena.deinit();
4523 const analysis_arena_allocator = analysis_arena.allocator();4531 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
4525 var sema: Sema = .{4536 var sema: Sema = .{
4526 .mod = mod,4537 .mod = mod,
4527 .gpa = gpa,4538 .gpa = gpa,
...@@ -4535,6 +4546,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4535,6 +4546,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4535 .fn_ret_ty = Type.void,4546 .fn_ret_ty = Type.void,
4536 .owner_func = null,4547 .owner_func = null,
4537 .owner_func_index = .none,4548 .owner_func_index = .none,
4549 .comptime_mutable_decls = &comptime_mutable_decls,
4538 };4550 };
4539 defer sema.deinit();4551 defer sema.deinit();
45404552
...@@ -4577,6 +4589,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4577,6 +4589,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4577 const body = zir.extra[extra.end..][0..extra.data.body_len];4589 const body = zir.extra[extra.end..][0..extra.data.body_len];
4578 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;4590 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
4579 try wip_captures.finalize();4591 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 }
4580 const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 };4596 const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 };
4581 const section_src: LazySrcLoc = .{ .node_offset_var_decl_section = 0 };4597 const section_src: LazySrcLoc = .{ .node_offset_var_decl_section = 0 };
4582 const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };4598 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...@@ -5486,6 +5502,9 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
5486 const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);5502 const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
5487 defer decl.value_arena.?.release(&decl_arena);5503 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
5489 const fn_ty = decl.ty;5508 const fn_ty = decl.ty;
5490 const fn_ty_info = mod.typeToFunc(fn_ty).?;5509 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...@@ -5503,6 +5522,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
5503 .owner_func = func,5522 .owner_func = func,
5504 .owner_func_index = func_index.toOptional(),5523 .owner_func_index = func_index.toOptional(),
5505 .branch_quota = @max(func.branch_quota, Sema.default_branch_quota),5524 .branch_quota = @max(func.branch_quota, Sema.default_branch_quota),
5525 .comptime_mutable_decls = &comptime_mutable_decls,
5506 };5526 };
5507 defer sema.deinit();5527 defer sema.deinit();
55085528
...@@ -5642,6 +5662,10 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE...@@ -5642,6 +5662,10 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
5642 }5662 }
56435663
5644 try wip_captures.finalize();5664 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
5646 // Copy the block into place and mark that as the main block.5670 // Copy the block into place and mark that as the main block.
5647 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +5671 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,...@@ -92,6 +92,14 @@ no_partial_func_ty: bool = false,
92/// here so the values can be dropped without any cleanup.92/// here so the values can be dropped without any cleanup.
93unresolved_inferred_allocs: std.AutoHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{},93unresolved_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
95const std = @import("std");103const std = @import("std");
96const math = std.math;104const math = std.math;
97const mem = std.mem;105const mem = std.mem;
...@@ -2545,6 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2545,6 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2545 },2553 },
2546 });2554 });
2547 try sema.maybeQueueFuncBodyAnalysis(decl_index);2555 try sema.maybeQueueFuncBodyAnalysis(decl_index);
2556 try sema.comptime_mutable_decls.append(decl_index);
2548 return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{2557 return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{
2549 .ty = ptr_ty.toIntern(),2558 .ty = ptr_ty.toIntern(),
2550 .addr = .{ .mut_decl = .{2559 .addr = .{ .mut_decl = .{
...@@ -7761,6 +7770,7 @@ fn resolveGenericInstantiationType(...@@ -7761,6 +7770,7 @@ fn resolveGenericInstantiationType(
7761 .is_generic_instantiation = true,7770 .is_generic_instantiation = true,
7762 .branch_quota = sema.branch_quota,7771 .branch_quota = sema.branch_quota,
7763 .branch_count = sema.branch_count,7772 .branch_count = sema.branch_count,
7773 .comptime_mutable_decls = sema.comptime_mutable_decls,
7764 };7774 };
7765 defer child_sema.deinit();7775 defer child_sema.deinit();
77667776
...@@ -31863,7 +31873,24 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi...@@ -31863,7 +31873,24 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
31863 var analysis_arena = std.heap.ArenaAllocator.init(gpa);31873 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
31864 defer analysis_arena.deinit();31874 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 };
31867 defer sema.deinit();31894 defer sema.deinit();
3186831895
31869 var wip_captures = try WipCaptureScope.init(gpa, decl.src_scope);31896 var wip_captures = try WipCaptureScope.init(gpa, decl.src_scope);
...@@ -31899,6 +31926,10 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi...@@ -31899,6 +31926,10 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
31899 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);31926 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
31900 struct_obj.backing_int_ty = backing_int_ty;31927 struct_obj.backing_int_ty = backing_int_ty;
31901 try wip_captures.finalize();31928 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 }
31902 } else {31933 } else {
31903 if (fields_bit_sum > std.math.maxInt(u16)) {31934 if (fields_bit_sum > std.math.maxInt(u16)) {
31904 var sema: Sema = .{31935 var sema: Sema = .{
...@@ -31914,6 +31945,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi...@@ -31914,6 +31945,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
31914 .fn_ret_ty = Type.void,31945 .fn_ret_ty = Type.void,
31915 .owner_func = null,31946 .owner_func = null,
31916 .owner_func_index = .none,31947 .owner_func_index = .none,
31948 .comptime_mutable_decls = undefined,
31917 };31949 };
31918 defer sema.deinit();31950 defer sema.deinit();
3191931951
...@@ -32603,6 +32635,9 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32603,6 +32635,9 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32603 var analysis_arena = std.heap.ArenaAllocator.init(gpa);32635 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
32604 defer analysis_arena.deinit();32636 defer analysis_arena.deinit();
3260532637
32638 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
32639 defer comptime_mutable_decls.deinit();
32640
32606 var sema: Sema = .{32641 var sema: Sema = .{
32607 .mod = mod,32642 .mod = mod,
32608 .gpa = gpa,32643 .gpa = gpa,
...@@ -32616,6 +32651,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32616,6 +32651,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32616 .fn_ret_ty = Type.void,32651 .fn_ret_ty = Type.void,
32617 .owner_func = null,32652 .owner_func = null,
32618 .owner_func_index = .none,32653 .owner_func_index = .none,
32654 .comptime_mutable_decls = &comptime_mutable_decls,
32619 };32655 };
32620 defer sema.deinit();32656 defer sema.deinit();
3262132657
...@@ -32886,6 +32922,10 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32886,6 +32922,10 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32886 }32922 }
32887 }32923 }
32888 try wip_captures.finalize();32924 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
32890 struct_obj.have_field_inits = true;32930 struct_obj.have_field_inits = true;
32891}32931}
...@@ -32945,6 +32985,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32945,6 +32985,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32945 var analysis_arena = std.heap.ArenaAllocator.init(gpa);32985 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
32946 defer analysis_arena.deinit();32986 defer analysis_arena.deinit();
3294732987
32988 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
32989 defer comptime_mutable_decls.deinit();
32990
32948 var sema: Sema = .{32991 var sema: Sema = .{
32949 .mod = mod,32992 .mod = mod,
32950 .gpa = gpa,32993 .gpa = gpa,
...@@ -32958,6 +33001,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32958,6 +33001,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32958 .fn_ret_ty = Type.void,33001 .fn_ret_ty = Type.void,
32959 .owner_func = null,33002 .owner_func = null,
32960 .owner_func_index = .none,33003 .owner_func_index = .none,
33004 .comptime_mutable_decls = &comptime_mutable_decls,
32961 };33005 };
32962 defer sema.deinit();33006 defer sema.deinit();
3296333007
...@@ -32984,6 +33028,10 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32984,6 +33028,10 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32984 }33028 }
3298533029
32986 try wip_captures.finalize();33030 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
32988 try union_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);33036 try union_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
3298933037
...@@ -33821,6 +33869,7 @@ fn analyzeComptimeAlloc(...@@ -33821,6 +33869,7 @@ fn analyzeComptimeAlloc(
33821 const decl = sema.mod.declPtr(decl_index);33869 const decl = sema.mod.declPtr(decl_index);
33822 decl.@"align" = alignment;33870 decl.@"align" = alignment;
3382333871
33872 try sema.comptime_mutable_decls.append(decl_index);
33824 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);33873 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
33825 return sema.addConstant(ptr_type, (try sema.mod.intern(.{ .ptr = .{33874 return sema.addConstant(ptr_type, (try sema.mod.intern(.{ .ptr = .{
33826 .ty = ptr_type.toIntern(),33875 .ty = ptr_type.toIntern(),