--- 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: "); 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");