]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
login, mount: fix __SC_GETPW_R_SIZE_MAX usage
authorKarel Zak <kzak@redhat.com>
Tue, 15 Dec 2015 11:25:56 +0000 (12:25 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 15 Dec 2015 11:33:34 +0000 (12:33 +0100)
sysconf(_SC_GETPW_R_SIZE_MAX) returns initial suggested size for pwd
buffer (see getpwnam_r man page or POSIX). This is not large enough in
some cases.

Yes, this sysconf option is misnamed (should be _SC_GETPW_R_SIZE_MIN).

Signed-off-by: Karel Zak <kzak@redhat.com>
include/c.h
libmount/src/utils.c
login-utils/login.c

index 2a317eb52f791977e8f61b4d512947a39576d4a3..ca028baeeeab2c474f3eebb02e26f926ca20b65e 100644 (file)
@@ -346,4 +346,13 @@ static inline int xusleep(useconds_t usec)
 # define UL_ASAN_BLACKLIST     /* nothing */
 #endif
 
+
+
+/*
+ * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
+ * pwd buffer and in some cases it is not large enough. See POSIX and
+ * getpwnam_r man page for more details.
+ */
+#define UL_GETPW_BUFSIZ        (16 * 1024)
+
 #endif /* UTIL_LINUX_C_H */
index e57eb33ba30a8fff2cf9d256a27e92ef24431d6b..39f6c851e4c2925b27cc3324e6e44b468291fc84 100644 (file)
@@ -635,16 +635,6 @@ int mnt_get_filesystems(char ***filesystems, const char *pattern)
        return rc;
 }
 
-static size_t get_pw_record_size(void)
-{
-#ifdef _SC_GETPW_R_SIZE_MAX
-       long sz = sysconf(_SC_GETPW_R_SIZE_MAX);
-       if (sz > 0)
-               return sz;
-#endif
-       return 16384;
-}
-
 /*
  * Returns an allocated string with username or NULL.
  */
@@ -652,14 +642,13 @@ char *mnt_get_username(const uid_t uid)
 {
         struct passwd pwd;
        struct passwd *res;
-       size_t sz = get_pw_record_size();
        char *buf, *username = NULL;
 
-       buf = malloc(sz);
+       buf = malloc(UL_GETPW_BUFSIZ);
        if (!buf)
                return NULL;
 
-       if (!getpwuid_r(uid, &pwd, buf, sz, &res) && res)
+       if (!getpwuid_r(uid, &pwd, buf, UL_GETPW_BUFSIZ, &res) && res)
                username = strdup(pwd.pw_name);
 
        free(buf);
@@ -671,17 +660,16 @@ int mnt_get_uid(const char *username, uid_t *uid)
        int rc = -1;
         struct passwd pwd;
        struct passwd *pw;
-       size_t sz = get_pw_record_size();
        char *buf;
 
        if (!username || !uid)
                return -EINVAL;
 
-       buf = malloc(sz);
+       buf = malloc(UL_GETPW_BUFSIZ);
        if (!buf)
                return -ENOMEM;
 
-       if (!getpwnam_r(username, &pwd, buf, sz, &pw) && pw) {
+       if (!getpwnam_r(username, &pwd, buf, UL_GETPW_BUFSIZ, &pw) && pw) {
                *uid= pw->pw_uid;
                rc = 0;
        } else {
@@ -699,17 +687,16 @@ int mnt_get_gid(const char *groupname, gid_t *gid)
        int rc = -1;
         struct group grp;
        struct group *gr;
-       size_t sz = get_pw_record_size();
        char *buf;
 
        if (!groupname || !gid)
                return -EINVAL;
 
-       buf = malloc(sz);
+       buf = malloc(UL_GETPW_BUFSIZ);
        if (!buf)
                return -ENOMEM;
 
-       if (!getgrnam_r(groupname, &grp, buf, sz, &gr) && gr) {
+       if (!getgrnam_r(groupname, &grp, buf, UL_GETPW_BUFSIZ, &gr) && gr) {
                *gid= gr->gr_gid;
                rc = 0;
        } else {
index b70846771c49db3bb0e9faec9072b84b56bf8728..2551631d30f29c29d320027b1195b0eebeed81e4 100644 (file)
@@ -674,22 +674,14 @@ static struct passwd *get_passwd_entry(const char *username,
                                         struct passwd *pwd)
 {
        struct passwd *res = NULL;
-       size_t sz = 16384;
        int x;
 
        if (!pwdbuf || !username)
                return NULL;
 
-#ifdef _SC_GETPW_R_SIZE_MAX
-       {
-               long xsz = sysconf(_SC_GETPW_R_SIZE_MAX);
-               if (xsz > 0)
-                       sz = (size_t) xsz;
-       }
-#endif
-       *pwdbuf = xrealloc(*pwdbuf, sz);
+       *pwdbuf = xrealloc(*pwdbuf, UL_GETPW_BUFSIZ);
 
-       x = getpwnam_r(username, pwd, *pwdbuf, sz, &res);
+       x = getpwnam_r(username, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res);
        if (!res) {
                errno = x;
                return NULL;