authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-25 13:36:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-25 13:36:15-07:00
logea6a076065efb6de5450d945540f825523d5d6e3
tree54c840d016aab9c07fb41f593b282d02e672aae6
parent84d50c892d41850f666f05e05472c23ffabee434

stage2: fix use-after-free in elf linker code


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

src-self-hosted/link/Elf.zig+25-2
...@@ -1348,6 +1348,7 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {...@@ -1348,6 +1348,7 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {
1348 var already_have_free_list_node = false;1348 var already_have_free_list_node = false;
1349 {1349 {
1350 var i: usize = 0;1350 var i: usize = 0;
1351 // TODO turn text_block_free_list into a hash map
1351 while (i < self.text_block_free_list.items.len) {1352 while (i < self.text_block_free_list.items.len) {
1352 if (self.text_block_free_list.items[i] == text_block) {1353 if (self.text_block_free_list.items[i] == text_block) {
1353 _ = self.text_block_free_list.swapRemove(i);1354 _ = self.text_block_free_list.swapRemove(i);
...@@ -1359,11 +1360,19 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {...@@ -1359,11 +1360,19 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {
1359 i += 1;1360 i += 1;
1360 }1361 }
1361 }1362 }
1363 // TODO process free list for dbg info just like we do above for vaddrs
13621364
1363 if (self.last_text_block == text_block) {1365 if (self.last_text_block == text_block) {
1364 // TODO shrink the .text section size here1366 // TODO shrink the .text section size here
1365 self.last_text_block = text_block.prev;1367 self.last_text_block = text_block.prev;
1366 }1368 }
1369 if (self.dbg_info_decl_first == text_block) {
1370 self.dbg_info_decl_first = text_block.dbg_info_next;
1371 }
1372 if (self.dbg_info_decl_last == text_block) {
1373 // TODO shrink the .debug_info section size here
1374 self.dbg_info_decl_last = text_block.dbg_info_prev;
1375 }
13671376
1368 if (text_block.prev) |prev| {1377 if (text_block.prev) |prev| {
1369 prev.next = text_block.next;1378 prev.next = text_block.next;
...@@ -1382,6 +1391,20 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {...@@ -1382,6 +1391,20 @@ fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {
1382 } else {1391 } else {
1383 text_block.next = null;1392 text_block.next = null;
1384 }1393 }
1394
1395 if (text_block.dbg_info_prev) |prev| {
1396 prev.dbg_info_next = text_block.dbg_info_next;
1397
1398 // TODO the free list logic like we do for text blocks above
1399 } else {
1400 text_block.dbg_info_prev = null;
1401 }
1402
1403 if (text_block.dbg_info_next) |next| {
1404 next.dbg_info_prev = text_block.dbg_info_prev;
1405 } else {
1406 text_block.dbg_info_next = null;
1407 }
1385}1408}
13861409
1387fn shrinkTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64) void {1410fn shrinkTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64) void {
...@@ -1583,10 +1606,10 @@ pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {...@@ -1583,10 +1606,10 @@ pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {
1583 next.prev = null;1606 next.prev = null;
1584 }1607 }
1585 if (self.dbg_line_fn_first == &decl.fn_link.elf) {1608 if (self.dbg_line_fn_first == &decl.fn_link.elf) {
1586 self.dbg_line_fn_first = null;1609 self.dbg_line_fn_first = decl.fn_link.elf.next;
1587 }1610 }
1588 if (self.dbg_line_fn_last == &decl.fn_link.elf) {1611 if (self.dbg_line_fn_last == &decl.fn_link.elf) {
1589 self.dbg_line_fn_last = null;1612 self.dbg_line_fn_last = decl.fn_link.elf.prev;
1590 }1613 }
1591}1614}
15921615