Page MenuHomeFreeBSD

D27370.diff
No OneTemporary

D27370.diff

Index: head/lib/libutil/getlocalbase.3
===================================================================
--- head/lib/libutil/getlocalbase.3
+++ head/lib/libutil/getlocalbase.3
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 18, 2020
+.Dd November 25, 2020
.Dt GETLOCALBASE 3
.Os
.Sh NAME
@@ -59,7 +59,7 @@
.Pa /usr/local
is used.
.Pp
-The value returned by the
+The contents of the string returned by the
.Fn getlocalbase
function shall not be modified.
.Sh IMPLEMENTATION NOTES
@@ -67,13 +67,34 @@
.Fn getlocalbase
will perform a setugid check on the running binary before checking the
environment.
+.Pp
+The address returned by
+.Fn getlocalbase
+will point into the executing processes environment if it is the result of
+.Fn getenv "LOCALBASE" ,
+to a static buffer if it is the result of
+.Fn sysctl "user.localbase" ,
+and to a constant string if the compiled in default value is returned.
+.Pp
+The same value will be returned on successive calls during the run-time
+of the program, ignoring any changes to the environment variable or the
+sysctl value that might have been made.
+.Pp
+The
+.Fn getlocalbase
+function can be compiled with a non-default value of LOCALBASE_CTL_LEN.
+A value of 0 will disable fetching of the sysctl value, a value less than
+MAXPATHLEN will put a limit on the maximum string length supported for
+this sysctl value.
+If built with a non-default value of LOCALBASE_CTL_LEN, a value of the
+user.localbase sysctl variable longer than this value will make
+.Fn getlocalbase
+return a valid string that is not a valid path prefix in any filesystem.
.Sh RETURN VALUES
The
.Fn getlocalbase
-function always succeeds and returns a pointer to a string, whose length
-may exceed MAXPATHLEN if it has been derived from the environment variable
-LOCALBASE.
-No length checks are performed on the result.
+function returns a pointer to a string, whose length may exceed MAXPATHLEN,
+if it has been obtained from the environment.
.Sh ENVIRONMENT
The
.Fn getlocalbase
@@ -83,7 +104,7 @@
.Sh ERRORS
The
.Fn getlocalbase
-function always succeeds.
+function always succeeds and returns a valid pointer to a string.
.Sh SEE ALSO
.Xr env 1 ,
.Xr src.conf 5 ,
Index: head/lib/libutil/getlocalbase.c
===================================================================
--- head/lib/libutil/getlocalbase.c
+++ head/lib/libutil/getlocalbase.c
@@ -31,6 +31,7 @@
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/limits.h>
+#include <errno.h>
#include <stdlib.h>
#include <paths.h>
#include <libutil.h>
@@ -40,35 +41,50 @@
#define _PATH_LOCALBASE "/usr/local"
#endif
+#ifndef LOCALBASE_CTL_LEN
+#define LOCALBASE_CTL_LEN MAXPATHLEN
+#endif
+
+/* Any prefix guaranteed to not be the start of a valid path name */
+#define ILLEGAL_PREFIX "/dev/null/"
+
const char *
getlocalbase(void)
{
- static const int localbase_oid[2] = {CTL_USER, USER_LOCALBASE};
+#if LOCALBASE_CTL_LEN > 0
+ int localbase_oid[2] = {CTL_USER, USER_LOCALBASE};
+ static char localpath[LOCALBASE_CTL_LEN];
+ size_t localpathlen = LOCALBASE_CTL_LEN;
+#endif
char *tmppath;
- size_t tmplen;
static const char *localbase = NULL;
+ if (localbase != NULL)
+ return (localbase);
+
if (issetugid() == 0) {
tmppath = getenv("LOCALBASE");
- if (tmppath != NULL && tmppath[0] != '\0')
- return (tmppath);
- }
- if (sysctl(localbase_oid, 2, NULL, &tmplen, NULL, 0) == 0 &&
- (tmppath = malloc(tmplen)) != NULL &&
- sysctl(localbase_oid, 2, tmppath, &tmplen, NULL, 0) == 0) {
- /*
- * Check for some other thread already having
- * set localbase - this should use atomic ops.
- * The amount of memory allocated above may leak,
- * if a parallel update in another thread is not
- * detected and the non-NULL pointer is overwritten.
- */
- if (tmppath[0] != '\0' &&
- (volatile const char*)localbase == NULL)
+ if (tmppath != NULL && tmppath[0] != '\0') {
localbase = tmppath;
+ return (localbase);
+ }
+ }
+
+#if LOCALBASE_CTL_LEN > 0
+ if (sysctl(localbase_oid, 2, localpath, &localpathlen, NULL, 0) != 0) {
+ if (errno != ENOMEM)
+ localbase = _PATH_LOCALBASE;
else
- free((void*)tmppath);
- return (localbase);
+ localbase = ILLEGAL_PREFIX;
+ } else {
+ if (localpath[0] != '\0')
+ localbase = localpath;
+ else
+ localbase = _PATH_LOCALBASE;
}
- return (_PATH_LOCALBASE);
+#else
+ localbase = _PATH_LOCALBASE;
+#endif
+
+ return (localbase);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 25, 6:32 PM (21 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12725818
Default Alt Text
D27370.diff (4 KB)

Event Timeline