From 4d77ef25f948cac32e4d5fd3f9df019e728fcb45 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 14 Apr 2022 15:16:51 +0200 Subject: [PATCH] elf: check symtab section headers size when writing globals Without this, it may happen we write the globals without extending the symtab section header's size. This can potentially lead to clobbering some data in the file, or simply omitting the globals from the symtab when displaying with support tooling such as `readelf`. --- src/link/Elf.zig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index bb13aad3a6ee90db3c2d2e2f78ceac7a5070a659..add23113a7af6d2244fd7181388a32ec70a23d4d 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2799,6 +2799,22 @@ fn writeAllGlobalSymbols(self: *Elf) !void { .p32 => @sizeOf(elf.Elf32_Sym), .p64 => @sizeOf(elf.Elf64_Sym), }; + const sym_align: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Sym), + .p64 => @alignOf(elf.Elf64_Sym), + }; + const needed_size = (self.local_symbols.items.len + self.global_symbols.items.len) * sym_size; + if (needed_size > self.allocatedSize(syms_sect.sh_offset)) { + // Move all the symbols to a new file location. + const new_offset = self.findFreeSpace(needed_size, sym_align); + const existing_size = @as(u64, syms_sect.sh_info) * sym_size; + const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size); + if (amt != existing_size) return error.InputOutput; + syms_sect.sh_offset = new_offset; + } + syms_sect.sh_size = needed_size; // anticipating adding the global symbols later + self.shdr_table_dirty = true; // TODO look into only writing one section + const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size; switch (self.ptr_width) { -- 2.54.0