aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Eßer <se@FreeBSD.org>2020-10-31 23:48:41 +0000
committerStefan Eßer <se@FreeBSD.org>2020-10-31 23:48:41 +0000
commit1ebef47735cbe16360fc456cc88971e5cc4cee22 (patch)
treea9155c14dd08d7f6477d9f90a605f6e4c9e93b2a /lib
parent113ec54c58a90f3bd71778b869e9cff5849ee9dc (diff)
downloadsrc-1ebef47735cbe16360fc456cc88971e5cc4cee22.tar.gz
src-1ebef47735cbe16360fc456cc88971e5cc4cee22.zip
Make sysctl user.local a tunable that can be written at run-time
This sysctl value had been provided as a read-only variable that is compiled into the C library based on the value of _PATH_LOCALBASE in paths.h. After this change, the value is compiled into the kernel as an empty string, which is translated to _PATH_LOCALBASE by the C library. This empty string can be overridden at boot time or by a privileged user at run time and will then be returned by sysctl. When set to an empty string, the value returned by sysctl reverts to _PATH_LOCALBASE. This update does not change the behavior on any system that does not modify the default value of user.localbase. I consider this change as experimental and would prefer if the run-time write permission was reconsidered and the sysctl variable defined with CLFLAG_RDTUN instead to restrict it to be set at boot time. MFC after: 1 month
Notes
Notes: svn path=/head/; revision=367243
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/sysctl.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/lib/libc/gen/sysctl.c b/lib/libc/gen/sysctl.c
index ac6140013038..6015d68e8c60 100644
--- a/lib/libc/gen/sysctl.c
+++ b/lib/libc/gen/sysctl.c
@@ -68,14 +68,14 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
if (retval || name[0] != CTL_USER)
return (retval);
- if (newp != NULL) {
- errno = EPERM;
- return (-1);
- }
if (namelen != 2) {
errno = EINVAL;
return (-1);
}
+ if (newp != NULL && name[1] != USER_LOCALBASE) {
+ errno = EPERM;
+ return (-1);
+ }
switch (name[1]) {
case USER_CS_PATH:
@@ -88,13 +88,21 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH));
return (0);
case USER_LOCALBASE:
- if (oldp != NULL && orig_oldlen < sizeof(_PATH_LOCALBASE)) {
- errno = ENOMEM;
- return (-1);
+ if (oldlenp != NULL) {
+ if (oldp == NULL) {
+ if (*oldlenp == 1)
+ *oldlenp = sizeof(_PATH_LOCALBASE);
+ } else {
+ if (*oldlenp != 1)
+ return (retval);
+ if (orig_oldlen < sizeof(_PATH_LOCALBASE)) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ *oldlenp = sizeof(_PATH_LOCALBASE);
+ memmove(oldp, _PATH_LOCALBASE, sizeof(_PATH_LOCALBASE));
+ }
}
- *oldlenp = sizeof(_PATH_LOCALBASE);
- if (oldp != NULL)
- memmove(oldp, _PATH_LOCALBASE, sizeof(_PATH_LOCALBASE));
return (0);
}