From ea6a076065efb6de5450d945540f825523d5d6e3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 25 Aug 2020 13:36:15 -0700 Subject: [PATCH] stage2: fix use-after-free in elf linker code --- src-self-hosted/link/Elf.zig | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/link/Elf.zig b/src-self-hosted/link/Elf.zig index eeb0289b05..1d18344cbb 100644 --- a/src-self-hosted/link/Elf.zig +++ b/src-self-hosted/link/Elf.zig @@ -1348,6 +1348,7 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void { var already_have_free_list_node = false; { var i: usize = 0; + // TODO turn text_block_free_list into a hash map while (i < self.text_block_free_list.items.len) { if (self.text_block_free_list.items[i] == text_block) { _ = self.text_block_free_list.swapRemove(i); @@ -1359,11 +1360,19 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void { i += 1; } } + // TODO process free list for dbg info just like we do above for vaddrs if (self.last_text_block == text_block) { // TODO shrink the .text section size here self.last_text_block = text_block.prev; } + if (self.dbg_info_decl_first == text_block) { + self.dbg_info_decl_first = text_block.dbg_info_next; + } + if (self.dbg_info_decl_last == text_block) { + // TODO shrink the .debug_info section size here + self.dbg_info_decl_last = text_block.dbg_info_prev; + } if (text_block.prev) |prev| { prev.next = text_block.next; @@ -1382,6 +1391,20 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void { } else { text_block.next = null; } + + if (text_block.dbg_info_prev) |prev| { + prev.dbg_info_next = text_block.dbg_info_next; + + // TODO the free list logic like we do for text blocks above + } else { + text_block.dbg_info_prev = null; + } + + if (text_block.dbg_info_next) |next| { + next.dbg_info_prev = text_block.dbg_info_prev; + } else { + text_block.dbg_info_next = null; + } } fn shrinkTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64) void { @@ -1583,10 +1606,10 @@ pub fn freeDecl(self: *Elf, decl: *Module.Decl) void { next.prev = null; } if (self.dbg_line_fn_first == &decl.fn_link.elf) { - self.dbg_line_fn_first = null; + self.dbg_line_fn_first = decl.fn_link.elf.next; } if (self.dbg_line_fn_last == &decl.fn_link.elf) { - self.dbg_line_fn_last = null; + self.dbg_line_fn_last = decl.fn_link.elf.prev; } }