The branch main has been updated by se:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9535d9f104d82487abfc3a64de18f9d010bba6d2

commit 9535d9f104d82487abfc3a64de18f9d010bba6d2
Author:     Stefan Eßer <[email protected]>
AuthorDate: 2022-02-05 12:33:53 +0000
Commit:     Stefan Eßer <[email protected]>
CommitDate: 2022-02-05 12:33:53 +0000

    libc: add helper furnction to set sysctl() user.* variables
    
    Testing had revealed that trying to retrieve the user.localbase
    variable into to small a buffer would return the correct error code,
    but would not fill the available buffer space with a partial result.
    
    A partial result is of no use, but this is still a violation of the
    documented behavior, which has been fixed in the previous commit to
    this function.
    
    I just checked the code for "user.cs_path" and found that it had the
    same issue.
    
    Instead of fixing the logic for each user.* sysctl string variable
    individually, this commit adds a helper function set_user_str() that
    implements the semantics specified in the sysctl() man page.
    
    It is currently only used for "user.cs_path" and "user.localbase",
    but it will offer a significant simplification when further such
    variables will be added (as I intend to do).
    
    MFC after:      3 days
---
 lib/libc/gen/sysctl.c | 45 +++++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/lib/libc/gen/sysctl.c b/lib/libc/gen/sysctl.c
index 9dd80ddfc0d8..59242b50bbed 100644
--- a/lib/libc/gen/sysctl.c
+++ b/lib/libc/gen/sysctl.c
@@ -46,6 +46,25 @@ __FBSDID("$FreeBSD$");
 extern int __sysctl(const int *name, u_int namelen, void *oldp,
     size_t *oldlenp, const void *newp, size_t newlen);
 
+static int
+set_user_str(void *dstp, size_t *dstlenp, const char *src, size_t len,
+    size_t maxlen)
+{
+       int retval;
+
+       retval = 0;
+       if (dstp != NULL) {
+               if (len > maxlen) {
+                       len = maxlen;
+                       errno = ENOMEM;
+                       retval = -1;
+               }
+               memcpy(dstp, src, len);
+       }
+       *dstlenp = len;
+       return (retval);
+}
+
 int
 sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
     const void *newp, size_t newlen)
@@ -74,18 +93,10 @@ 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) {
-                       *oldlenp = sizeof(_PATH_LOCALBASE);
-                       if (oldp != NULL) {
-                               if (*oldlenp > orig_oldlen) {
-                                       *oldlenp = orig_oldlen;
-                                       errno = ENOMEM;
-                                       retval = -1;
-                               }
-                               memmove(oldp, _PATH_LOCALBASE, *oldlenp);
-                       }
-               }
-               return (retval);
+               if (oldlenp == NULL || *oldlenp > sizeof(""))
+                       return (0);
+               return (set_user_str(oldp, oldlenp, _PATH_LOCALBASE,
+                       sizeof(_PATH_LOCALBASE), orig_oldlen));
        }
 
        /* Variables under CLT_USER whose values are immutably defined below */
@@ -96,14 +107,8 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t 
*oldlenp,
 
        switch (name[1]) {
        case USER_CS_PATH:
-               if (oldp != NULL && orig_oldlen < sizeof(_PATH_STDPATH)) {
-                       errno = ENOMEM;
-                       return (-1);
-               }
-               *oldlenp = sizeof(_PATH_STDPATH);
-               if (oldp != NULL)
-                       memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH));
-               return (0);
+               return (set_user_str(oldp, oldlenp, _PATH_STDPATH,
+                   sizeof(_PATH_STDPATH), orig_oldlen));
        }
 
        if (oldp != NULL && *oldlenp < sizeof(int)) {

Reply via email to