authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-12-05 16:31:47+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-12-05 16:31:47+01:00
logee1630beeaaa24cb6d65631517afabc0621b902f
treef524ba20b6608fbbb316f95c6caf8df63dc18508
parent205857e3429da161c46870df84b286345353c5cf

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


3 files changed, 25 insertions(+), 12 deletions(-)

src/link/Elf.zig+6-1
...@@ -1160,6 +1160,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1160,6 +1160,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1160 };1160 };
1161 }1161 }
11621162
1163 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1164
1163 // Init all objects1165 // Init all objects
1164 for (self.objects.items) |index| {1166 for (self.objects.items) |index| {
1165 try self.file(index).?.object.init(self);1167 try self.file(index).?.object.init(self);
...@@ -1168,6 +1170,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1168,6 +1170,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1168 try self.file(index).?.shared_object.init(self);1170 try self.file(index).?.shared_object.init(self);
1169 }1171 }
11701172
1173 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1174
1171 // Dedup shared objects1175 // Dedup shared objects
1172 {1176 {
1173 var seen_dsos = std.StringHashMap(void).init(gpa);1177 var seen_dsos = std.StringHashMap(void).init(gpa);
...@@ -1294,6 +1298,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1294,6 +1298,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1294 self.error_flags.no_entry_point_found = false;1298 self.error_flags.no_entry_point_found = false;
1295 try self.writeElfHeader();1299 try self.writeElfHeader();
1296 }1300 }
1301
1302 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1297}1303}
12981304
1299pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {1305pub 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...@@ -2803,7 +2809,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
2803 }));2809 }));
2804 } else {2810 } else {
2805 self.error_flags.missing_libc = true;2811 self.error_flags.missing_libc = true;
2806 return error.FlushFailure;
2807 }2812 }
2808 }2813 }
2809 }2814 }
src/link/Elf/Object.zig+18-6
...@@ -72,7 +72,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {...@@ -72,7 +72,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
72 {72 {
73 try elf_file.reportParseError2(73 try elf_file.reportParseError2(
74 self.index,74 self.index,
75 "corrupted header: section header table extends past the end of file",75 "corrupt header: section header table extends past the end of file",
76 .{},76 .{},
77 );77 );
78 return error.MalformedObject;78 return error.MalformedObject;
...@@ -86,14 +86,23 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {...@@ -86,14 +86,23 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
86 try self.shdrs.ensureTotalCapacityPrecise(gpa, shdrs.len);86 try self.shdrs.ensureTotalCapacityPrecise(gpa, shdrs.len);
8787
88 for (shdrs) |shdr| {88 for (shdrs) |shdr| {
89 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {89 if (shdr.sh_type != elf.SHT_NOBITS) {
90 try elf_file.reportParseError2(self.index, "corrupted section header", .{});90 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {
91 return error.MalformedObject;91 try elf_file.reportParseError2(self.index, "corrupt section: extends past the end of file", .{});
92 return error.MalformedObject;
93 }
92 }94 }
93 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));95 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));
94 }96 }
9597
96 try self.strtab.appendSlice(gpa, self.shdrContents(self.header.?.e_shstrndx));98 const shstrtab = self.shdrContents(self.header.?.e_shstrndx);
99 for (shdrs) |shdr| {
100 if (shdr.sh_name >= shstrtab.len) {
101 try elf_file.reportParseError2(self.index, "corrupt section name offset", .{});
102 return error.MalformedObject;
103 }
104 }
105 try self.strtab.appendSlice(gpa, shstrtab);
97106
98 const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) {107 const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) {
99 elf.SHT_SYMTAB => break @as(u16, @intCast(i)),108 elf.SHT_SYMTAB => break @as(u16, @intCast(i)),
...@@ -105,7 +114,10 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {...@@ -105,7 +114,10 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
105 self.first_global = shdr.sh_info;114 self.first_global = shdr.sh_info;
106115
107 const raw_symtab = self.shdrContents(index);116 const raw_symtab = self.shdrContents(index);
108 const nsyms = @divExact(raw_symtab.len, @sizeOf(elf.Elf64_Sym));117 const nsyms = math.divExact(usize, raw_symtab.len, @sizeOf(elf.Elf64_Sym)) catch {
118 try elf_file.reportParseError2(self.index, "symbol table not evenly divisible", .{});
119 return error.MalformedObject;
120 };
109 const symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(raw_symtab.ptr))[0..nsyms];121 const symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(raw_symtab.ptr))[0..nsyms];
110122
111 const strtab_bias = @as(u32, @intCast(self.strtab.items.len));123 const strtab_bias = @as(u32, @intCast(self.strtab.items.len));
test/link/elf.zig+1-5
...@@ -1877,8 +1877,6 @@ fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step {...@@ -1877,8 +1877,6 @@ fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step {
1877 expectLinkErrors(exe, test_step, .{ .exact = &.{1877 expectLinkErrors(exe, test_step, .{ .exact = &.{
1878 "invalid cpu architecture: aarch64",1878 "invalid cpu architecture: aarch64",
1879 "note: while parsing /?/a.o",1879 "note: while parsing /?/a.o",
1880 "undefined symbol: foo",
1881 "note: referenced by /?/a.o:.text",
1882 } });1880 } });
18831881
1884 return test_step;1882 return test_step;
...@@ -3309,10 +3307,8 @@ fn testUnknownFileTypeError(b: *Build, opts: Options) *Step {...@@ -3309,10 +3307,8 @@ fn testUnknownFileTypeError(b: *Build, opts: Options) *Step {
3309 expectLinkErrors(exe, test_step, .{ .exact = &.{3307 expectLinkErrors(exe, test_step, .{ .exact = &.{
3310 "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)",3308 "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)",
3311 "note: while parsing /?/liba.dylib",3309 "note: while parsing /?/liba.dylib",
3312 "error: unexpected error: parsing input file failed with error InvalidLdScript",3310 "unexpected error: parsing input file failed with error InvalidLdScript",
3313 "note: while parsing /?/liba.dylib",3311 "note: while parsing /?/liba.dylib",
3314 "undefined symbol: foo",
3315 "note: referenced by /?/a.o:.text",
3316 } });3312 } });
33173313
3318 return test_step;3314 return test_step;