From d75659e3ac48efd21e61dae97634b76dcc67955c 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/tools/lxc_unshare.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/lxc/tools/lxc_unshare.c b/src/lxc/tools/lxc_unshare.c index 9c38f537f..5e1775f5e 100644 --- a/src/lxc/tools/lxc_unshare.c +++ b/src/lxc/tools/lxc_unshare.c @@ -68,29 +68,51 @@ static void usage(char *cmd) static bool lookup_user(const char *optarg, uid_t *uid) { char name[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.47.2