⬢ DragonFlyBSD Kernel Audit
DF-2957 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/subr_fattime.c	2026-06-29 12:51:19.000000000 +0000
+++ b/sys/kern/subr_fattime.c	2026-10-26 00:25:42.813042622 +0000
@@ -222,21 +222,39 @@
 {
 	unsigned day;
 
-	/* Unpack time fields */
-	tsp->tv_sec = (dt & 0x1f) << 1;
-	tsp->tv_sec += ((dt & 0x7e0) >> 5) * 60;
-	tsp->tv_sec += ((dt & 0xf800) >> 11) * 3600;
-	tsp->tv_sec += dh / 100;
-	tsp->tv_nsec = (dh % 100) * 10000000;
+	/* Unpack time fields (clamped: on-disk values may be out of range) */
+	{
+		unsigned ss = (dt & 0x1f) << 1;
+		unsigned mm = (dt & 0x7e0) >> 5;
+		unsigned hh = (dt & 0xf800) >> 11;
+		unsigned idx = (dd >> 5) & 0x3f;
+		unsigned mon = idx & 0x0f;
 
-	/* Day of month */
-	day = (dd & 0x1f) - 1;
+		if (ss > 59)
+			ss = 59;
+		if (mm > 59)
+			mm = 59;
+		if (hh > 23)
+			hh = 23;
+		if (mon < 1)
+			mon = 1;
+		if (mon > 12)
+			mon = 12;
+		tsp->tv_sec = ss;
+		tsp->tv_sec += mm * 60;
+		tsp->tv_sec += hh * 3600;
+		tsp->tv_sec += dh / 100;
+		tsp->tv_nsec = (dh % 100) * 10000000;
 
-	/* Full leap-year cycles */
-	day += LYC * ((dd >> 11) & 0x1f);
+		/* Day of month */
+		day = (dd & 0x1f) - 1;
 
-	/* Month offset from leap-year cycle */
-	day += daytab[(dd >> 5) & 0x3f];
+		/* Full leap-year cycles */
+		day += LYC * ((dd >> 11) & 0x1f);
+
+		/* Month offset from leap-year cycle */
+		day += daytab[(idx & 0x30) | mon];
+	}
 
 	/*
 	 * 2100 is not a leap year.