elf: exit early with an error when parsing or init failed

This commit is contained in:
Jakub Konka 2023-12-05 16:31:47 +01:00
parent 205857e342
commit ee1630beea
3 changed files with 25 additions and 12 deletions

View File

@ -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 // Init all objects
for (self.objects.items) |index| { for (self.objects.items) |index| {
try self.file(index).?.object.init(self); 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); try self.file(index).?.shared_object.init(self);
} }
if (self.misc_errors.items.len > 0) return error.FlushFailure;
// Dedup shared objects // Dedup shared objects
{ {
var seen_dsos = std.StringHashMap(void).init(gpa); 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; self.error_flags.no_entry_point_found = false;
try self.writeElfHeader(); 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 { 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 { } else {
self.error_flags.missing_libc = true; self.error_flags.missing_libc = true;
return error.FlushFailure;
} }
} }
} }

View File

@ -72,7 +72,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
{ {
try elf_file.reportParseError2( try elf_file.reportParseError2(
self.index, 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; return error.MalformedObject;
@ -86,14 +86,23 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
try self.shdrs.ensureTotalCapacityPrecise(gpa, shdrs.len); try self.shdrs.ensureTotalCapacityPrecise(gpa, shdrs.len);
for (shdrs) |shdr| { for (shdrs) |shdr| {
if (shdr.sh_type != elf.SHT_NOBITS) {
if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) { 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", .{}); try elf_file.reportParseError2(self.index, "corrupt section: extends past the end of file", .{});
return error.MalformedObject; return error.MalformedObject;
} }
}
self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr)); 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) { const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) {
elf.SHT_SYMTAB => break @as(u16, @intCast(i)), 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; self.first_global = shdr.sh_info;
const raw_symtab = self.shdrContents(index); 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 symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(raw_symtab.ptr))[0..nsyms];
const strtab_bias = @as(u32, @intCast(self.strtab.items.len)); const strtab_bias = @as(u32, @intCast(self.strtab.items.len));

View File

@ -1877,8 +1877,6 @@ fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step {
expectLinkErrors(exe, test_step, .{ .exact = &.{ expectLinkErrors(exe, test_step, .{ .exact = &.{
"invalid cpu architecture: aarch64", "invalid cpu architecture: aarch64",
"note: while parsing /?/a.o", "note: while parsing /?/a.o",
"undefined symbol: foo",
"note: referenced by /?/a.o:.text",
} }); } });
return test_step; return test_step;
@ -3309,10 +3307,8 @@ fn testUnknownFileTypeError(b: *Build, opts: Options) *Step {
expectLinkErrors(exe, test_step, .{ .exact = &.{ 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)", "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", "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", "note: while parsing /?/liba.dylib",
"undefined symbol: foo",
"note: referenced by /?/a.o:.text",
} }); } });
return test_step; return test_step;