DragonFlyBSD Kernel Audit
DF-0897 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/devfs/devfs_rules.c b/sys/vfs/devfs/devfs_rules.c
--- a/sys/vfs/devfs/devfs_rules.c
+++ b/sys/vfs/devfs/devfs_rules.c
@@ -88,8 +88,14 @@
 		goto error_out;
 		/* NOTREACHED */
 
-	len = strlen(templ->mntpoint);
-	if (len == 0)
+	/*
+	 * Use strnlen() bounded by PATH_MAX to prevent a non-NUL-terminated
+	 * string from causing strlen() to scan past the end of the embedded
+	 * char[PATH_MAX] array into adjacent struct fields.  Reject any input
+	 * that fills the entire array (no NUL terminator within PATH_MAX).
+	 */
+	len = strnlen(templ->mntpoint, PATH_MAX);
+	if (len == 0 || len >= PATH_MAX)
 		goto error_out;
 		/* NOTREACHED */
 
@@ -101,8 +107,8 @@
 			goto error_out;
 			/* NOTREACHED */
 
-		len = strlen(templ->name);
-		if (len == 0)
+		len = strnlen(templ->name, PATH_MAX);
+		if (len == 0 || len >= PATH_MAX)
 			goto error_out;
 			/* NOTREACHED */
 
@@ -115,8 +121,8 @@
 			goto error_out;
 			/* NOTREACHED */
 
-		len = strlen(templ->linkname);
-		if (len == 0)
+		len = strnlen(templ->linkname, PATH_MAX);
+		if (len == 0 || len >= PATH_MAX)
 			goto error_out;
 			/* NOTREACHED */
 

diff --git a/sys/vfs/devfs/devfs_core.c b/sys/vfs/devfs/devfs_core.c
--- a/sys/vfs/devfs/devfs_core.c
+++ b/sys/vfs/devfs/devfs_core.c
@@ -2029,12 +2029,20 @@
 {
 	char *name = NULL;
 	char *path = NULL;
-	size_t len = strlen(fullpath) + 1;
+	size_t len = strnlen(fullpath, PATH_MAX) + 1;
 	int i;
 
 	KKASSERT((fullpath != NULL) && (buf != NULL));
 	KKASSERT((pathp != NULL) && (namep != NULL));
 
+	/*
+	 * Defense in depth: callers pass name_buf[PATH_MAX], so bound the
+	 * copy to PATH_MAX+1 (NUL inclusive).  strnlen above ensures we
+	 * never read past PATH_MAX bytes even if fullpath lacks a NUL.
+	 */
+	if (len > PATH_MAX + 1)
+		len = PATH_MAX + 1;
+
 	memcpy(buf, fullpath, len);
 
 	for (i = len-1; i>= 0; i--) {