Commit af8621db2d

Jakub Konka <kubkon@jakubkonka.com>
2023-12-05 13:28:47
elf: report error at the point where it is happening
1 parent 72568c1
Changed files (2)
src
src/link/Elf/Object.zig
@@ -58,6 +58,17 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
 
     const gpa = elf_file.base.allocator;
 
+    if (self.data.len < self.header.?.e_shoff or
+        self.data.len < self.header.?.e_shoff + self.header.?.e_shnum * @sizeOf(elf.Elf64_Shdr))
+    {
+        try elf_file.reportParseError2(
+            self.index,
+            "corrupted header: section header table extends past the end of file",
+            .{},
+        );
+        return error.LinkFail;
+    }
+
     const shoff = math.cast(usize, self.header.?.e_shoff) orelse return error.Overflow;
     const shdrs = @as(
         [*]align(1) const elf.Elf64_Shdr,
@@ -66,6 +77,10 @@ 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.LinkFail;
+        }
         self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));
     }
 
src/link/Elf.zig
@@ -1760,6 +1760,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
 }
 
 const ParseError = error{
+    LinkFail,
     UnknownFileType,
     InvalidCpuArch,
     OutOfMemory,
@@ -1769,6 +1770,7 @@ const ParseError = error{
     FileSystem,
     NotSupported,
     InvalidCharacter,
+    MalformedObject,
 } || LdScript.Error || std.os.AccessError || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError;
 
 fn parsePositional(self: *Elf, path: []const u8, must_link: bool, ctx: *ParseErrorCtx) ParseError!void {
@@ -6057,6 +6059,7 @@ fn handleAndReportParseError(
 ) error{OutOfMemory}!void {
     const cpu_arch = self.base.options.target.cpu.arch;
     switch (err) {
+        error.LinkFail => {}, // already reported
         error.UnknownFileType => try self.reportParseError(path, "unknown file type", .{}),
         error.InvalidCpuArch => try self.reportParseError(
             path,
@@ -6082,6 +6085,17 @@ fn reportParseError(
     try err.addNote(self, "while parsing {s}", .{path});
 }
 
+pub fn reportParseError2(
+    self: *Elf,
+    file_index: File.Index,
+    comptime format: []const u8,
+    args: anytype,
+) error{OutOfMemory}!void {
+    var err = try self.addErrorWithNotes(1);
+    try err.addMsg(self, format, args);
+    try err.addNote(self, "while parsing {}", .{self.file(file_index).?.fmtPath()});
+}
+
 const FormatShdrCtx = struct {
     elf_file: *Elf,
     shdr: elf.Elf64_Shdr,