git: 330f1a42813e - stable/14 - libsa: smbios: Stop parsing on an End-of-Table structure

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Tue, 08 Apr 2025 13:41:05 UTC
The branch stable/14 has been updated by olce:

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

commit 330f1a42813e70186bdbef6ff22f24c61d36a24a
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-03-04 11:17:45 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-04-08 13:38:27 +0000

    libsa: smbios: Stop parsing on an End-of-Table structure
    
    This structure exists since SMBIOS v2.2 and indicates that there are no
    structures to be parsed beyond this point.  For backwards compatibility,
    the standard recommends that system software ensures that this structure
    covers the rest of the SMBIOS structure table area as reported by the
    Structure Table Address, and the Structure Table Maximum Size (64-bit
    entry point) or the Structure Table Length (32-bit entry point), which
    makes existing parsers continue to work correctly as they usually ignore
    unknown structure types.  However, this is not a requirement, so be
    bullet proof and immediately stop parsing in this case.
    
    Reviewed by:    imp, markj
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D49285
    
    (cherry picked from commit 7e61fc76400cce08de39adde99b879f0bca21b7d)
---
 stand/libsa/smbios.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/stand/libsa/smbios.c b/stand/libsa/smbios.c
index e726dfeb7af3..50cab3eee939 100644
--- a/stand/libsa/smbios.c
+++ b/stand/libsa/smbios.c
@@ -92,6 +92,7 @@
 #define	SMBIOS_SIG		"_SM_"
 #define	SMBIOS3_SIG		"_SM3_"
 #define	SMBIOS_DMI_SIG		"_DMI_"
+#define	SMBIOS_EOT_TYPE		0x7f
 
 /*
  * 5.1 General
@@ -504,6 +505,9 @@ smbios_parse_table(const caddr_t addr)
 			    (size & 0x7fff) : (size << 10);
 		break;
 
+	case SMBIOS_EOT_TYPE:	/* 3.3.42 End-of-Table (Type 127) */
+		return (NULL);
+
 	default:	/* skip other types */
 		break;
 	}
@@ -529,15 +533,19 @@ smbios_find_struct(int type)
 	ep = smbios.addr + smbios.length;
 	for (dmi = smbios.addr, i = 0;
 	     dmi < ep && i < smbios.count; i++) {
-		if (SMBIOS_GET8(dmi, 0) == type) {
-			return dmi;
-		}
+		const uint8_t seen_type = SMBIOS_GET8(dmi, 0);
+
+		if (seen_type == type)
+			return (dmi);
+		if (seen_type == SMBIOS_EOT_TYPE)
+			/* End of table. */
+			break;
 		/* Find structure terminator. */
 		dmi = SMBIOS_GETSTR(dmi);
-		while (SMBIOS_GET16(dmi, 0) != 0 && dmi < ep) {
+		while (SMBIOS_GET16(dmi, 0) != 0 && dmi < ep)
 			dmi++;
-		}
-		dmi += 2;	/* For checksum */
+		/* Skip it. */
+		dmi += 2;
 	}
 
 	return (NULL);
@@ -632,8 +640,8 @@ smbios_detect(const caddr_t addr)
 	if (smbios.addr == NULL)
 		return;
 
-	for (dmi = smbios.addr, i = 0;
-	     dmi < smbios.addr + smbios.length && i < smbios.count; i++)
+	for (dmi = smbios.addr, i = 0; dmi != NULL &&
+	    dmi < smbios.addr + smbios.length && i < smbios.count; i++)
 		dmi = smbios_parse_table(dmi);
 
 	setenv("smbios.entry_point_type",