Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107412930
D27370.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D27370.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 14, 7:21 PM (6 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15799999
Default Alt Text
D27370.diff (4 KB)
Attached To
Mode
D27370: New implementation of getlocalbase()
Attached
Detach File
Event Timeline
Log In to Comment