Index: lib/libutil/getlocalbase.c =================================================================== --- lib/libutil/getlocalbase.c +++ lib/libutil/getlocalbase.c @@ -41,29 +41,25 @@ ssize_t getlocalbase(char *path, size_t pathlen) { - ssize_t tmplen; + size_t tmplen, miblen; const char *tmppath; + int mib[4]; - if ((pathlen == 0) || (path == NULL)) { + /* It's unlikely that the buffer would be this big */ + if ((pathlen == 0) || (pathlen > SSIZE_MAX) || (path == NULL)) { errno = EINVAL; return (-1); } - /* It's unlikely that the buffer would be this big */ - if (pathlen > SSIZE_MAX) { - errno = ENOMEM; - return (-1); - } - tmppath = NULL; - tmplen = (size_t)pathlen; + tmplen = pathlen; if (issetugid() == 0) tmppath = getenv("LOCALBASE"); - if ((tmppath == NULL) && - (sysctlbyname("user.localbase", path, (size_t *)&tmplen, NULL, - 0) == 0)) { - return (tmplen); + if (tmppath == NULL) { + sysctlnametomib("user.localbase", mib, &miblen); + if (sysctl(mib, 4, path, &tmplen, NULL, 0) == 0) + return (tmplen); } if (tmppath == NULL) @@ -73,17 +69,20 @@ tmppath = "/usr/local"; #endif + /* + * If strlcpy() overflowed the size of the provided buffer then just + * return an error. + */ tmplen = strlcpy(path, tmppath, pathlen); - if ((tmplen < 0) || (tmplen >= (ssize_t)pathlen)) { + if (tmplen >= pathlen) { errno = ENOMEM; return (-1); } - /* It's unlikely that the buffer would be this big */ - if (tmplen > SSIZE_MAX) { - errno = ENOMEM; - return (-1); - } - + /* + * tmplen can't be larger than pathlen, and pathlen was already + * checked to make sure it wouldn't overflow the ssize_t. Thus this + * cast is safe. + */ return ((ssize_t)tmplen); }