aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Eßer <se@FreeBSD.org>2020-11-02 18:48:06 +0000
committerStefan Eßer <se@FreeBSD.org>2020-11-02 18:48:06 +0000
commit23b4092837404dc30b93034a0252100457c1e7e9 (patch)
tree6c121407d18e2d98ef79a908e06c06aac6055a88 /lib
parent7731194090ab632fa58fa1e58a3996428c30d388 (diff)
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/sysctl.c55
1 files changed, 27 insertions, 28 deletions
diff --git a/lib/libc/gen/sysctl.c b/lib/libc/gen/sysctl.c
index 6015d68e8c603..cdd2d3e391e6c 100644
--- a/lib/libc/gen/sysctl.c
+++ b/lib/libc/gen/sysctl.c
@@ -53,26 +53,42 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
int retval;
size_t orig_oldlen;
- orig_oldlen = oldlenp ? *oldlenp : 0;
+ orig_oldlen = oldlenp != NULL ? *oldlenp : 0;
retval = __sysctl(name, namelen, oldp, oldlenp, newp, newlen);
/*
- * All valid names under CTL_USER have a dummy entry in the sysctl
- * tree (to support name lookups and enumerations) with an
- * empty/zero value, and the true value is supplied by this routine.
- * For all such names, __sysctl() is used solely to validate the
- * name.
+ * Valid names under CTL_USER except USER_LOCALBASE have a dummy entry
+ * in the sysctl tree (to support name lookups and enumerations) with
+ * an empty/zero value, and the true value is supplied by this routine.
+ * For all such names, __sysctl() is used solely to validate the name.
*
- * Return here unless there was a successful lookup for a CTL_USER
- * name.
+ * Return here unless there was a successful lookup for a CTL_USER name.
*/
- if (retval || name[0] != CTL_USER)
+ if (retval != 0 || name[0] != CTL_USER)
return (retval);
if (namelen != 2) {
errno = EINVAL;
return (-1);
}
- if (newp != NULL && name[1] != USER_LOCALBASE) {
+
+ /* Variables under CLT_USER that may be overridden by kernel values */
+ switch (name[1]) {
+ case USER_LOCALBASE:
+ if (oldlenp == NULL || *oldlenp != 1)
+ return (0);
+ if (oldp != NULL) {
+ if (orig_oldlen < sizeof(_PATH_LOCALBASE)) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ memmove(oldp, _PATH_LOCALBASE, sizeof(_PATH_LOCALBASE));
+ }
+ *oldlenp = sizeof(_PATH_LOCALBASE);
+ return (0);
+ }
+
+ /* Variables under CLT_USER whose values are immutably defined below */
+ if (newp != NULL) {
errno = EPERM;
return (-1);
}
@@ -87,26 +103,9 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
if (oldp != NULL)
memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH));
return (0);
- case USER_LOCALBASE:
- 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));
- }
- }
- return (0);
}
- if (oldp && *oldlenp < sizeof(int)) {
+ if (oldp != NULL && *oldlenp < sizeof(int)) {
errno = ENOMEM;
return (-1);
}