⬢ DragonFlyBSD Kernel Audit
DF-5730 / fix.diff
← back to finding ↓ download raw
--- a/sys/ddb/db_variables.c
+++ b/sys/ddb/db_variables.c
@@ -40,19 +40,58 @@
 
 static int	db_find_variable (struct db_variable **varp);
 static void	db_write_variable (struct db_variable *, db_expr_t *);
+static int	db_radix_fcn (struct db_variable *, db_expr_t *, int);
+static int	db_maxoff_fcn (struct db_variable *, db_expr_t *, int);
 
 #ifdef notused
 static int	db_set_variable (db_expr_t value);
 #endif
 
 static struct db_variable db_vars[] = {
-	{ "radix",	&db_radix, NULL },
-	{ "maxoff",	&db_maxoff, NULL },
+	{ "radix",	&db_radix, db_radix_fcn },
+	{ "maxoff",	&db_maxoff, db_maxoff_fcn },
 	{ "maxwidth",	&db_max_width, NULL },
 	{ "tabstops",	&db_tab_stop_width, NULL },
 };
 static struct db_variable *db_evars = db_vars + NELEM(db_vars);
 
+/*
+ * $radix and $maxoff are settable from the ddb console with no other
+ * validation.  A radix outside {8,10,16} silently corrupts the expression
+ * language itself: db_lex() parses every subsequent number literal in that
+ * base and accepts digits invalid for it (db_lex.c:190-205), including the
+ * values of later `set' commands; recovery requires the forced 0x/0t
+ * prefixes.  A negative maxoff casts to ULONG_MAX and inverts the symbol
+ * attribution threshold (db_sym.c:289), misattributing distant raw
+ * addresses to unrelated symbols.  Complements DF-5724's fix, which adds
+ * validating setters for $tabstops and $maxwidth.
+ */
+static int
+db_radix_fcn(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+	if (op == DB_VAR_SET) {
+		if (*valuep != 8 && *valuep != 10 && *valuep != 16)
+			db_error("radix must be 8, 10 or 16\n");
+		db_radix = *valuep;
+	} else {
+		*valuep = db_radix;
+	}
+	return (0);
+}
+
+static int
+db_maxoff_fcn(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+	if (op == DB_VAR_SET) {
+		if (*valuep < 0)
+			db_error("maxoff must be >= 0\n");
+		db_maxoff = *valuep;
+	} else {
+		*valuep = db_maxoff;
+	}
+	return (0);
+}
+
 static int
 db_find_variable(struct db_variable **varp)
 {