05ad79
From 3d1333293ef48117060cd4e285e9c49a6d061e83 Mon Sep 17 00:00:00 2001
05ad79
From: Karel Zak <kzak@redhat.com>
05ad79
Date: Tue, 15 Dec 2015 12:25:56 +0100
05ad79
Subject: [PATCH 63/84] login, mount: fix __SC_GETPW_R_SIZE_MAX usage
05ad79
05ad79
sysconf(_SC_GETPW_R_SIZE_MAX) returns initial suggested size for pwd
05ad79
buffer (see getpwnam_r man page or POSIX). This is not large enough in
05ad79
some cases.
05ad79
05ad79
Yes, this sysconf option is misnamed (should be _SC_GETPW_R_SIZE_MIN).
05ad79
05ad79
Upstream: http://github.com/karelzak/util-linux/commit/f7ac9e71b18fa7314151f2ab65ee0bdd2ea89c07
05ad79
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1290689
05ad79
Signed-off-by: Karel Zak <kzak@redhat.com>
05ad79
---
05ad79
 include/c.h          |  7 +++++++
05ad79
 libmount/src/utils.c | 25 ++++++-------------------
05ad79
 login-utils/login.c  | 12 ++----------
05ad79
 3 files changed, 15 insertions(+), 29 deletions(-)
05ad79
05ad79
diff --git a/include/c.h b/include/c.h
05ad79
index a50e8a5..7b59ce8 100644
05ad79
--- a/include/c.h
05ad79
+++ b/include/c.h
05ad79
@@ -300,4 +300,11 @@ static inline int usleep(useconds_t usec)
05ad79
 # define SEEK_HOLE	4
05ad79
 #endif
05ad79
 
05ad79
+/*
05ad79
+ * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
05ad79
+ * pwd buffer and in some cases it is not large enough. See POSIX and
05ad79
+ * getpwnam_r man page for more details.
05ad79
+ */
05ad79
+#define UL_GETPW_BUFSIZ	(16 * 1024)
05ad79
+
05ad79
 #endif /* UTIL_LINUX_C_H */
05ad79
diff --git a/libmount/src/utils.c b/libmount/src/utils.c
05ad79
index 9305bb8..7c6f5b1 100644
05ad79
--- a/libmount/src/utils.c
05ad79
+++ b/libmount/src/utils.c
05ad79
@@ -538,16 +538,6 @@ int mnt_get_filesystems(char ***filesystems, const char *pattern)
05ad79
 	return rc;
05ad79
 }
05ad79
 
05ad79
-static size_t get_pw_record_size(void)
05ad79
-{
05ad79
-#ifdef _SC_GETPW_R_SIZE_MAX
05ad79
-	long sz = sysconf(_SC_GETPW_R_SIZE_MAX);
05ad79
-	if (sz > 0)
05ad79
-		return sz;
05ad79
-#endif
05ad79
-	return 16384;
05ad79
-}
05ad79
-
05ad79
 /*
05ad79
  * Returns allocated string with username or NULL.
05ad79
  */
05ad79
@@ -555,14 +545,13 @@ char *mnt_get_username(const uid_t uid)
05ad79
 {
05ad79
         struct passwd pwd;
05ad79
 	struct passwd *res;
05ad79
-	size_t sz = get_pw_record_size();
05ad79
 	char *buf, *username = NULL;
05ad79
 
05ad79
-	buf = malloc(sz);
05ad79
+	buf = malloc(UL_GETPW_BUFSIZ);
05ad79
 	if (!buf)
05ad79
 		return NULL;
05ad79
 
05ad79
-	if (!getpwuid_r(uid, &pwd, buf, sz, &res) && res)
05ad79
+	if (!getpwuid_r(uid, &pwd, buf, UL_GETPW_BUFSIZ, &res) && res)
05ad79
 		username = strdup(pwd.pw_name);
05ad79
 
05ad79
 	free(buf);
05ad79
@@ -574,17 +563,16 @@ int mnt_get_uid(const char *username, uid_t *uid)
05ad79
 	int rc = -1;
05ad79
         struct passwd pwd;
05ad79
 	struct passwd *pw;
05ad79
-	size_t sz = get_pw_record_size();
05ad79
 	char *buf;
05ad79
 
05ad79
 	if (!username || !uid)
05ad79
 		return -EINVAL;
05ad79
 
05ad79
-	buf = malloc(sz);
05ad79
+	buf = malloc(UL_GETPW_BUFSIZ);
05ad79
 	if (!buf)
05ad79
 		return -ENOMEM;
05ad79
 
05ad79
-	if (!getpwnam_r(username, &pwd, buf, sz, &pw) && pw) {
05ad79
+	if (!getpwnam_r(username, &pwd, buf, UL_GETPW_BUFSIZ, &pw) && pw) {
05ad79
 		*uid= pw->pw_uid;
05ad79
 		rc = 0;
05ad79
 	} else {
05ad79
@@ -602,17 +590,16 @@ int mnt_get_gid(const char *groupname, gid_t *gid)
05ad79
 	int rc = -1;
05ad79
         struct group grp;
05ad79
 	struct group *gr;
05ad79
-	size_t sz = get_pw_record_size();
05ad79
 	char *buf;
05ad79
 
05ad79
 	if (!groupname || !gid)
05ad79
 		return -EINVAL;
05ad79
 
05ad79
-	buf = malloc(sz);
05ad79
+	buf = malloc(UL_GETPW_BUFSIZ);
05ad79
 	if (!buf)
05ad79
 		return -ENOMEM;
05ad79
 
05ad79
-	if (!getgrnam_r(groupname, &grp, buf, sz, &gr) && gr) {
05ad79
+	if (!getgrnam_r(groupname, &grp, buf, UL_GETPW_BUFSIZ, &gr) && gr) {
05ad79
 		*gid= gr->gr_gid;
05ad79
 		rc = 0;
05ad79
 	} else {
05ad79
diff --git a/login-utils/login.c b/login-utils/login.c
05ad79
index a59dd3a..e0e960f 100644
05ad79
--- a/login-utils/login.c
05ad79
+++ b/login-utils/login.c
05ad79
@@ -671,22 +671,14 @@ static struct passwd *get_passwd_entry(const char *username,
05ad79
 					 struct passwd *pwd)
05ad79
 {
05ad79
 	struct passwd *res = NULL;
05ad79
-	size_t sz = 16384;
05ad79
 	int x;
05ad79
 
05ad79
 	if (!pwdbuf || !username)
05ad79
 		return NULL;
05ad79
 
05ad79
-#ifdef _SC_GETPW_R_SIZE_MAX
05ad79
-	{
05ad79
-		long xsz = sysconf(_SC_GETPW_R_SIZE_MAX);
05ad79
-		if (xsz > 0)
05ad79
-			sz = (size_t) xsz;
05ad79
-	}
05ad79
-#endif
05ad79
-	*pwdbuf = xrealloc(*pwdbuf, sz);
05ad79
+	*pwdbuf = xrealloc(*pwdbuf, UL_GETPW_BUFSIZ);
05ad79
 
05ad79
-	x = getpwnam_r(username, pwd, *pwdbuf, sz, &res;;
05ad79
+	x = getpwnam_r(username, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res;;
05ad79
 	if (!res) {
05ad79
 		errno = x;
05ad79
 		return NULL;
05ad79
-- 
05ad79
2.7.4
05ad79