git: dc3d0ff61575 - stable/12 - etdump: exit on error if section header or entry offset is OOB

From: Ed Maste <emaste_at_FreeBSD.org>
Date: Thu, 23 Mar 2023 12:50:29 UTC
The branch stable/12 has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=dc3d0ff61575870614ba3691a0cbbbf8f6ff2065

commit dc3d0ff61575870614ba3691a0cbbbf8f6ff2065
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2022-05-03 20:13:37 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2023-03-23 12:49:43 +0000

    etdump: exit on error if section header or entry offset is OOB
    
    PR:             263663
    Reported by:    Robert Morris <rtm@lcs.mit.edu>
    Reviewed by:    markj
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D35868
    
    (cherry picked from commit ddf77ec392717e7eaf278c0f201b561afac97b87)
---
 usr.bin/etdump/etdump.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/usr.bin/etdump/etdump.c b/usr.bin/etdump/etdump.c
index aedd53a9f6d1..38220c821439 100644
--- a/usr.bin/etdump/etdump.c
+++ b/usr.bin/etdump/etdump.c
@@ -116,8 +116,8 @@ boot_catalog_valid(char *entry)
 }
 
 static int
-dump_section(char *buffer, size_t offset, FILE *outfile, const char *filename,
-    struct outputter *outputter)
+dump_section(char *buffer, size_t bufsize, size_t offset, FILE *outfile,
+    const char *filename, struct outputter *outputter)
 {
 	boot_catalog_section_header *sh;
 	u_char platform_id;
@@ -125,6 +125,8 @@ dump_section(char *buffer, size_t offset, FILE *outfile, const char *filename,
 	size_t entry_offset;
 	boot_catalog_section_entry *entry;
 
+	if (offset + sizeof(boot_catalog_section_header) > bufsize)
+		errx(1, "%s: section header out of bounds", filename);
 	sh = (boot_catalog_section_header *)&buffer[offset];
 	if (outputter->output_section != NULL) {
 		outputter->output_section(outfile, filename, sh);
@@ -135,6 +137,10 @@ dump_section(char *buffer, size_t offset, FILE *outfile, const char *filename,
 	if (outputter->output_entry != NULL) {
 		for (i = 1; i <= (int)sh->num_section_entries[0]; i++) {
 			entry_offset = offset + i * ET_BOOT_ENTRY_SIZE;
+			if (entry_offset + sizeof(boot_catalog_section_entry) >
+			    bufsize)
+				errx(1, "%s: section entry out of bounds",
+				    filename);
 			entry =
 			    (boot_catalog_section_entry *)&buffer[entry_offset];
 			outputter->output_entry(outfile, filename, entry,
@@ -195,8 +201,8 @@ dump_eltorito(FILE *iso, const char *filename, FILE *outfile,
 		    (uint8_t)entry[0] != ET_SECTION_HEADER_LAST)
 			break;
 
-		entry_count = dump_section(buffer, offset, outfile, filename,
-		    outputter);
+		entry_count = dump_section(buffer, sizeof(buffer), offset,
+		    outfile, filename, outputter);
 
 		offset += entry_count * ET_BOOT_ENTRY_SIZE;
 	}