DragonFlyBSD Kernel Audit
DF-0451 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netgraph/netgraph/ng_parse.c b/sys/netgraph/netgraph/ng_parse.c
--- a/sys/netgraph/netgraph/ng_parse.c
+++ b/sys/netgraph/netgraph/ng_parse.c
@@ -787,9 +787,22 @@
 	const u_char *data, int *off, char *cbuf, int cbuflen)
 {
 	const struct ng_parse_fixedstring_info *const fi = type->info;
-	int error, temp = *off;
+	/*
+	 * DF-0451 defense-in-depth: ng_string_unparse() uses unbounded
+	 * strlen(raw) on the field, which can run off the end of the kernel
+	 * allocation when the field is not NUL-terminated.  Copy at most
+	 * fi->bufSize bytes into a stack buffer and NUL-terminate it so the
+	 * subsequent strlen() is bounded to exactly the field size.
+	 */
+	char nulbuf[NG_PATHSIZ + 1];	/* NG_PATHSIZ is the largest fixedstring */
+	int error, temp = 0;
 
-	if ((error = ng_string_unparse(type, data, &temp, cbuf, cbuflen)) != 0)
+	KKASSERT(fi->bufSize <= NG_PATHSIZ);
+	bcopy(data + *off, nulbuf, fi->bufSize);
+	nulbuf[fi->bufSize] = '\0';
+
+	if ((error = ng_string_unparse(type, (const u_char *)nulbuf,
+	     &temp, cbuf, cbuflen)) != 0)
 		return (error);
 	*off += fi->bufSize;
 	return (0);