]> git.proxmox.com Git - mirror_lxc.git/commitdiff
fix getpwuid() thread safe issue
authorDonghwa Jeong <dh48.jeong@samsung.com>
Thu, 14 Jun 2018 06:32:03 +0000 (15:32 +0900)
committerDonghwa Jeong <dh48.jeong@samsung.com>
Thu, 14 Jun 2018 06:32:03 +0000 (15:32 +0900)
Signed-off-by: Donghwa Jeong <dh48.jeong@samsung.com>
src/lxc/attach.c
src/lxc/cmd/lxc_user_nic.c
src/lxc/cmd/lxc_usernsexec.c
src/lxc/conf.c

index 9bbdd0e6a0b509447a2c1d0d55e4d9bf623d05b7..dd98a6d331042aec9e28a660658cbc8f172655d1 100644 (file)
@@ -1501,14 +1501,32 @@ int lxc_attach_run_command(void* payload)
 int lxc_attach_run_shell(void* payload)
 {
        uid_t uid;
-       struct passwd *passwd;
+       struct passwd pwent;
+       struct passwd *pwentp = NULL;
        char *user_shell;
+       char *buf;
+       size_t bufsize;
+       int ret;
 
        /* Ignore payload parameter. */
        (void)payload;
 
        uid = getuid();
-       passwd = getpwuid(uid);
+
+       bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+       if (bufsize == -1)
+               bufsize = 1024;
+
+       buf = malloc(bufsize);
+       if (buf) {
+               ret = getpwuid_r(uid, &pwent, buf, bufsize, &pwentp);
+               if (!pwentp) {
+                       if (ret == 0)
+                               WARN("Could not find matched password record.");
+
+                       WARN("Failed to get password record - %u", uid);
+               }
+       }
 
        /* This probably happens because of incompatible nss implementations in
         * host and container (remember, this code is still using the host's
@@ -1516,10 +1534,10 @@ int lxc_attach_run_shell(void* payload)
         * the information by spawning a [getent passwd uid] process and parsing
         * the result.
         */
-       if (!passwd)
+       if (!pwentp)
                user_shell = lxc_attach_getpwshell(uid);
        else
-               user_shell = passwd->pw_shell;
+               user_shell = pwent.pw_shell;
        if (user_shell)
                execlp(user_shell, user_shell, (char *)NULL);
 
@@ -1528,7 +1546,8 @@ int lxc_attach_run_shell(void* payload)
         */
        execlp("/bin/sh", "/bin/sh", (char *)NULL);
        SYSERROR("Failed to execute shell");
-       if (!passwd)
+       if (!pwentp)
                free(user_shell);
+       free(buf);
        return -1;
 }
index d071ce0b5af30ee619a25a74aa2ea2a33c571ba6..2b0ee6059709ac732969a2e7f5452b4dacd6f6a7 100644 (file)
@@ -103,15 +103,35 @@ static int open_and_lock(char *path)
 
 static char *get_username(void)
 {
-       struct passwd *pwd;
+       struct passwd pwent;
+       struct passwd *pwentp = NULL;
+       char *buf;
+       char *username;
+       size_t bufsize;
+       int ret;
+
+       bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+       if (bufsize == -1)
+               bufsize = 1024;
+
+       buf = malloc(bufsize);
+       if (!buf)
+               return NULL;
+
+       ret = getpwuid_r(getuid(), &pwent, buf, bufsize, &pwentp);
+       if (!pwentp) {
+               if (ret == 0)
+                       usernic_error("%s", "Could not find matched password record\n");
 
-       pwd = getpwuid(getuid());
-       if (!pwd) {
-               usernic_error("Failed to get username: %s\n", strerror(errno));
+               usernic_error("Failed to get username: %s(%u)\n", strerror(errno), getuid());
+               free(buf);
                return NULL;
        }
 
-       return pwd->pw_name;
+       username = strdup(pwent.pw_name);
+       free(buf);
+
+       return username;
 }
 
 static void free_groupnames(char **groupnames)
@@ -1170,6 +1190,7 @@ int main(int argc, char *argv[])
        }
 
        n = get_alloted(me, args.type, args.link, &alloted);
+       free(me);
 
        if (request == LXC_USERNIC_DELETE) {
                int ret;
index 725796270a4ce689212fdee6037769a54ffeed67..56e1bdbcb2c314c70118076fe2ed3a75555bfd04 100644 (file)
@@ -253,14 +253,42 @@ static int read_default_map(char *fnam, int which, char *username)
 
 static int find_default_map(void)
 {
-       struct passwd *p = getpwuid(getuid());
-       if (!p)
+       struct 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 -1;
-       if (read_default_map(subuidfile, ID_TYPE_UID, p->pw_name) < 0)
+
+       ret = getpwuid_r(getuid(), &pwent, buf, bufsize, &pwentp);
+       if (!pwentp) {
+               if (ret == 0)
+                       printf("WARN: could not find matched password record\n");
+
+               printf("Failed to get password record - %u\n", getuid());
+               free(buf);
                return -1;
-       if (read_default_map(subgidfile, ID_TYPE_GID, p->pw_name) < 0)
+       }
+
+       if (read_default_map(subuidfile, ID_TYPE_UID, pwent.pw_name) < 0) {
+               free(buf);
                return -1;
-    return 0;
+       }
+
+       if (read_default_map(subgidfile, ID_TYPE_GID, pwent.pw_name) < 0) {
+               free(buf);
+               return -1;
+       }
+
+       free(buf);
+       return 0;
 }
 
 int main(int argc, char *argv[])
index c5586b33c2ad67995d4b85d1a7d6b278169c28a1..66f5c915b9730600289881be8c4f1c0fd8721ea5 100644 (file)
@@ -4508,13 +4508,35 @@ on_error:
 /* not thread-safe, do not use from api without first forking */
 static char *getuname(void)
 {
-       struct passwd *result;
+       struct passwd pwent;
+       struct passwd *pwentp = NULL;
+       char *buf;
+       char *username;
+       size_t bufsize;
+       int ret;
 
-       result = getpwuid(geteuid());
-       if (!result)
+       bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+       if (bufsize == -1)
+               bufsize = 1024;
+
+       buf = malloc(bufsize);
+       if (!buf)
                return NULL;
 
-       return strdup(result->pw_name);
+       ret = getpwuid_r(geteuid(), &pwent, buf, bufsize, &pwentp);
+       if (!pwentp) {
+               if (ret == 0)
+                       WARN("Could not find matched password record.");
+
+               ERROR("Failed to get password record - %u", geteuid());
+               free(buf);
+               return NULL;
+       }
+
+       username = strdup(pwent.pw_name);
+       free(buf);
+
+       return username;
 }
 
 /* not thread-safe, do not use from api without first forking */