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 */