DF-0897 / fix.diff
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--) { |