diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-12-05 16:31:47 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-12-05 16:31:47 +0100 |
| commit | ee1630beeaaa24cb6d65631517afabc0621b902f (patch) | |
| tree | f524ba20b6608fbbb316f95c6caf8df63dc18508 | |
| parent | 205857e3429da161c46870df84b286345353c5cf (diff) | |
| download | zig-ee1630beeaaa24cb6d65631517afabc0621b902f.tar.gz zig-ee1630beeaaa24cb6d65631517afabc0621b902f.zip | |
elf: exit early with an error when parsing or init failed
| -rw-r--r-- | src/link/Elf.zig | 7 | ||||
| -rw-r--r-- | src/link/Elf/Object.zig | 24 | ||||
| -rw-r--r-- | test/link/elf.zig | 6 |
3 files changed, 25 insertions, 12 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 9a76a794fe..81b1ec5b6c 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1160,6 +1160,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node }; } + if (self.misc_errors.items.len > 0) return error.FlushFailure; + // Init all objects for (self.objects.items) |index| { try self.file(index).?.object.init(self); @@ -1168,6 +1170,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node try self.file(index).?.shared_object.init(self); } + if (self.misc_errors.items.len > 0) return error.FlushFailure; + // Dedup shared objects { var seen_dsos = std.StringHashMap(void).init(gpa); @@ -1294,6 +1298,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node self.error_flags.no_entry_point_found = false; try self.writeElfHeader(); } + + if (self.misc_errors.items.len > 0) return error.FlushFailure; } pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void { @@ -2803,7 +2809,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v })); } else { self.error_flags.missing_libc = true; - return error.FlushFailure; } } } diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index dc02021f93..6b0cc66c33 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -72,7 +72,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { { try elf_file.reportParseError2( self.index, - "corrupted header: section header table extends past the end of file", + "corrupt header: section header table extends past the end of file", .{}, ); return error.MalformedObject; @@ -86,14 +86,23 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { try self.shdrs.ensureTotalCapacityPrecise(gpa, shdrs.len); for (shdrs) |shdr| { - if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) { - try elf_file.reportParseError2(self.index, "corrupted section header", .{}); - return error.MalformedObject; + if (shdr.sh_type != elf.SHT_NOBITS) { + if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) { + try elf_file.reportParseError2(self.index, "corrupt section: extends past the end of file", .{}); + return error.MalformedObject; + } } self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr)); } - try self.strtab.appendSlice(gpa, self.shdrContents(self.header.?.e_shstrndx)); + const shstrtab = self.shdrContents(self.header.?.e_shstrndx); + for (shdrs) |shdr| { + if (shdr.sh_name >= shstrtab.len) { + try elf_file.reportParseError2(self.index, "corrupt section name offset", .{}); + return error.MalformedObject; + } + } + try self.strtab.appendSlice(gpa, shstrtab); const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { elf.SHT_SYMTAB => break @as(u16, @intCast(i)), @@ -105,7 +114,10 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { self.first_global = shdr.sh_info; const raw_symtab = self.shdrContents(index); - const nsyms = @divExact(raw_symtab.len, @sizeOf(elf.Elf64_Sym)); + const nsyms = math.divExact(usize, raw_symtab.len, @sizeOf(elf.Elf64_Sym)) catch { + try elf_file.reportParseError2(self.index, "symbol table not evenly divisible", .{}); + return error.MalformedObject; + }; const symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(raw_symtab.ptr))[0..nsyms]; const strtab_bias = @as(u32, @intCast(self.strtab.items.len)); diff --git a/test/link/elf.zig b/test/link/elf.zig index e730644dff..c2ed3e08b4 100644 --- a/test/link/elf.zig +++ b/test/link/elf.zig @@ -1877,8 +1877,6 @@ fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step { expectLinkErrors(exe, test_step, .{ .exact = &.{ "invalid cpu architecture: aarch64", "note: while parsing /?/a.o", - "undefined symbol: foo", - "note: referenced by /?/a.o:.text", } }); return test_step; @@ -3309,10 +3307,8 @@ fn testUnknownFileTypeError(b: *Build, opts: Options) *Step { expectLinkErrors(exe, test_step, .{ .exact = &.{ "invalid token in LD script: '\\x00\\x00\\x00\\x0c\\x00\\x00\\x00/usr/lib/dyld\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0d' (0:829)", "note: while parsing /?/liba.dylib", - "error: unexpected error: parsing input file failed with error InvalidLdScript", + "unexpected error: parsing input file failed with error InvalidLdScript", "note: while parsing /?/liba.dylib", - "undefined symbol: foo", - "note: referenced by /?/a.o:.text", } }); return test_step; |
