⬢ DragonFlyBSD Kernel Audit
DF-2327 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/ppbus/ppbconf.c
+++ b/sys/bus/ppbus/ppbconf.c
@@ -210,6 +210,23 @@
  *
  * Returns the class id. of the peripherial, -1 otherwise
  */
+/*
+ * DF-2327: search_token(..., ":") returns NULL when the field carries no
+ * colon; ppb_pnp_detect computed NULL+1 and handed it to kprintf %s (an
+ * immediate kernel page fault on a malicious peripheral).  Return a safe
+ * empty string instead.
+ */
+static char *
+ppb_pnp_field(char *token)
+{
+	char *val;
+
+	val = search_token(token, UNKNOWN_LENGTH, ":");
+	if (val == NULL)
+		return ("");
+	return (val + 1);
+}
+
 static int
 ppb_pnp_detect(device_t bus)
 {
@@ -246,37 +263,32 @@
 
 	if ((token = search_token(str, len, "MFG")) != NULL ||
 		(token = search_token(str, len, "MANUFACTURER")) != NULL)
-		kprintf("ppbus%d: <%s", unit,
-			search_token(token, UNKNOWN_LENGTH, ":") + 1);
+		kprintf("ppbus%d: <%s", unit, ppb_pnp_field(token));
 	else
 		kprintf("ppbus%d: <unknown", unit);
 
 	if ((token = search_token(str, len, "MDL")) != NULL ||
 		(token = search_token(str, len, "MODEL")) != NULL)
-		kprintf(" %s",
-			search_token(token, UNKNOWN_LENGTH, ":") + 1);
+		kprintf(" %s", ppb_pnp_field(token));
 	else
 		kprintf(" unknown");
 
 	if ((token = search_token(str, len, "VER")) != NULL)
-		kprintf("/%s",
-			search_token(token, UNKNOWN_LENGTH, ":") + 1);
+		kprintf("/%s", ppb_pnp_field(token));
 
 	if ((token = search_token(str, len, "REV")) != NULL)
-		kprintf(".%s",
-			search_token(token, UNKNOWN_LENGTH, ":") + 1);
+		kprintf(".%s", ppb_pnp_field(token));
 
 	kprintf(">");
 
 	if ((token = search_token(str, len, "CLS")) != NULL) {
-		class = search_token(token, UNKNOWN_LENGTH, ":") + 1;
+		class = ppb_pnp_field(token);
 		kprintf(" %s", class);
 	}
 
 	if ((token = search_token(str, len, "CMD")) != NULL ||
 		(token = search_token(str, len, "COMMAND")) != NULL)
-		kprintf(" %s",
-			search_token(token, UNKNOWN_LENGTH, ":") + 1);
+		kprintf(" %s", ppb_pnp_field(token));
 
 	kprintf("\n");