1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

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
This commit is contained in:
Stefan Eßer 2022-02-04 13:44:20 +01:00
parent 9596b349bb
commit e11ad014d1

View File

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