git: e11ad014d146 - main - libc: return partial sysctl() result if buffer is too small
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 04 Feb 2022 13:10:36 UTC
The branch main has been updated by se:
URL: https://cgit.FreeBSD.org/src/commit/?id=e11ad014d1468729ecf758ab3709618a78feae1b
commit e11ad014d1468729ecf758ab3709618a78feae1b
Author: Stefan Eßer <se@FreeBSD.org>
AuthorDate: 2022-02-04 12:44:20 +0000
Commit: Stefan Eßer <se@FreeBSD.org>
CommitDate: 2022-02-04 12:44:20 +0000
libc: return partial sysctl() result if buffer is too small
Testing of a new feature revealed that calling sysctl() to retrieve
the value of the user.localbase variable passing too low a buffer size
could leave the result buffer unchanged.
The behavior in the normal case of a sufficiently large buffer was
correct.
All known callers pass a sufficiently large buffer and have thus not
been affected by this issue. If a non-default value had been assigned
to this variable, the result was as documented, too.
Fix the function to fill the buffer with a partial result, if the
passed in buffer size is too low to hold the full result.
MFC after: 3 days
---
lib/libc/gen/sysctl.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/lib/libc/gen/sysctl.c b/lib/libc/gen/sysctl.c
index cdd2d3e391e6..9dd80ddfc0d8 100644
--- a/lib/libc/gen/sysctl.c
+++ b/lib/libc/gen/sysctl.c
@@ -74,17 +74,18 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
/* 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);
+ if (oldlenp != NULL && *oldlenp == 1) {
+ *oldlenp = sizeof(_PATH_LOCALBASE);
+ if (oldp != NULL) {
+ if (*oldlenp > orig_oldlen) {
+ *oldlenp = orig_oldlen;
+ errno = ENOMEM;
+ retval = -1;
+ }
+ memmove(oldp, _PATH_LOCALBASE, *oldlenp);
}
- memmove(oldp, _PATH_LOCALBASE, sizeof(_PATH_LOCALBASE));
}
- *oldlenp = sizeof(_PATH_LOCALBASE);
- return (0);
+ return (retval);
}
/* Variables under CLT_USER whose values are immutably defined below */