From 2dce415b621e4c7cc78f679f8ec54a5b401c785b Mon Sep 17 00:00:00 2001 From: Donghwa Jeong Date: Tue, 12 Jun 2018 17:09:13 +0900 Subject: [PATCH] fix getpwnam() thread safe issue Signed-off-by: Donghwa Jeong --- src/lxc/pam/pam_cgfs.c | 28 +++++++++++++++++++++++----- src/lxc/tools/lxc_unshare.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/lxc/pam/pam_cgfs.c b/src/lxc/pam/pam_cgfs.c index d5196f8a0..81ce912e8 100644 --- a/src/lxc/pam/pam_cgfs.c +++ b/src/lxc/pam/pam_cgfs.c @@ -1520,14 +1520,32 @@ static void cg_escape(void) /* Get uid and gid for @user. */ static bool get_uid_gid(const char *user, uid_t *uid, gid_t *gid) { - struct passwd *pwent; + strcut passwd pwent; + struct passwd *pwentp = NULL; + char *buf; + size_t bufsize; + int ret; + + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) + bufsize = 1024; + + buf = malloc(bufsize); + if (!buf) + return false; + + ret = getpwnam_r(user, &pwent, buf, bufsize, &pwentp); + if (!pwentp) { + if (ret == 0) + mysyslog(LOG_ERR, "Could not find matched password record.\n", NULL); - pwent = getpwnam(user); - if (!pwent) + free(buf); return false; + } - *uid = pwent->pw_uid; - *gid = pwent->pw_gid; + *uid = pwent.pw_uid; + *gid = pwent.pw_gid; + free(buf); return true; } diff --git a/src/lxc/tools/lxc_unshare.c b/src/lxc/tools/lxc_unshare.c index 54f0fd545..eb69068af 100644 --- a/src/lxc/tools/lxc_unshare.c +++ b/src/lxc/tools/lxc_unshare.c @@ -82,29 +82,51 @@ static void usage(char *cmd) static bool lookup_user(const char *optarg, uid_t *uid) { char name[TOOL_MAXPATHLEN]; - struct passwd *pwent = NULL; + struct passwd pwent; + struct passwd *pwentp = NULL; + char *buf; + size_t bufsize; + int ret; if (!optarg || (optarg[0] == '\0')) return false; + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) + bufsize = 1024; + + buf = malloc(bufsize); + if (!buf) + return false; + if (sscanf(optarg, "%u", uid) < 1) { /* not a uid -- perhaps a username */ if (sscanf(optarg, "%s", name) < 1) return false; - pwent = getpwnam(name); - if (!pwent) { + ret = getpwnam_r(name, &pwent, buf, bufsize, &pwentp); + if (!pwentp) { + if (ret == 0) + fprintf(stderr, "could not find matched password record\n"); + fprintf(stderr, "invalid username %s\n", name); + free(buf); return false; } - *uid = pwent->pw_uid; + *uid = pwent.pw_uid; } else { - pwent = getpwuid(*uid); - if (!pwent) { + ret = getpwuid_r(*uid, &pwent, buf, bufsize, &pwentp); + if (!pwentp) { + if (ret == 0) + fprintf(stderr, "could not find matched password record\n"); + fprintf(stderr, "invalid uid %u\n", *uid); + free(buf); return false; } } + + free(buf); return true; } -- 2.39.2