⬢ DragonFlyBSD Kernel Audit
DF-5724 / fix.diff
← back to finding ↓ download raw
--- a/sys/ddb/db_output.c	2026-10-10 17:47:35.412259038 +0000
+++ b/sys/ddb/db_output.c	2026-10-10 17:47:35.432258780 +0000
@@ -62,7 +62,14 @@
 static int	db_output_position = 0;		/* output column */
 static int	db_last_non_space = 0;		/* last non-space character */
 db_expr_t	db_tab_stop_width = 8;		/* how wide are tab stops? */
-#define	NEXT_TAB(i)	rounddown((i) + db_tab_stop_width, db_tab_stop_width)
+/*
+ * db_tab_stop_width is operator-settable ($tabstops); keep NEXT_TAB
+ * total even if a bogus value sneaks in: rounddown(x, 0) is a #DE and
+ * rounddown(x, <0) makes db_force_whitespace() spin forever.
+ */
+#define	NEXT_TAB(i)	(db_tab_stop_width > 0 ?				\
+			 rounddown((i) + db_tab_stop_width, db_tab_stop_width) : \
+			 (i) + 8)
 db_expr_t	db_max_width = 79;		/* output line width */
 
 static void db_putchar (int c, void *arg);

--- a/sys/ddb/db_variables.c	2026-10-10 17:47:35.412259038 +0000
+++ b/sys/ddb/db_variables.c	2026-10-10 17:47:35.436258729 +0000
@@ -40,6 +40,8 @@
 
 static int	db_find_variable (struct db_variable **varp);
 static void	db_write_variable (struct db_variable *, db_expr_t *);
+static int	db_max_width_fcn (struct db_variable *, db_expr_t *, int);
+static int	db_tab_stop_width_fcn (struct db_variable *, db_expr_t *, int);
 
 #ifdef notused
 static int	db_set_variable (db_expr_t value);
@@ -48,11 +50,43 @@
 static struct db_variable db_vars[] = {
 	{ "radix",	&db_radix, NULL },
 	{ "maxoff",	&db_maxoff, NULL },
-	{ "maxwidth",	&db_max_width, NULL },
-	{ "tabstops",	&db_tab_stop_width, NULL },
+	{ "maxwidth",	&db_max_width, db_max_width_fcn },
+	{ "tabstops",	&db_tab_stop_width, db_tab_stop_width_fcn },
 };
 static struct db_variable *db_evars = db_vars + NELEM(db_vars);
 
+/*
+ * $maxwidth and $tabstops are settable from the ddb console with no
+ * other validation.  tabstops==0 makes db_force_whitespace() divide by
+ * zero (fatal trap 18 cascade, wedged machine); tabstops<0 makes it
+ * spin forever with all CPUs stopped.  Refuse nonsense values.
+ */
+static int
+db_tab_stop_width_fcn(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+	if (op == DB_VAR_SET) {
+		if (*valuep < 1)
+			db_error("tabstops must be >= 1\n");
+		db_tab_stop_width = *valuep;
+	} else {
+		*valuep = db_tab_stop_width;
+	}
+	return (0);
+}
+
+static int
+db_max_width_fcn(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+	if (op == DB_VAR_SET) {
+		if (*valuep < 1)
+			db_error("maxwidth must be >= 1\n");
+		db_max_width = *valuep;
+	} else {
+		*valuep = db_max_width;
+	}
+	return (0);
+}
+
 static int
 db_find_variable(struct db_variable **varp)
 {