Make tzplatform_context_set_user() to be multi-thread-safe 81/160681/1 accepted/tizen/unified/20171120.065120 submit/tizen/20171117.115655
authorHyotaek Shim <hyotaek.shim@samsung.com>
Fri, 17 Nov 2017 09:21:49 +0000 (18:21 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Fri, 17 Nov 2017 11:55:43 +0000 (11:55 +0000)
Change-Id: Ica378036e8bbe0756543d3ec796f7549b9f4f1c7
Signed-off-by: Hyotaek Shim <hyotaek.shim@samsung.com>
(cherry picked from commit eb4ba339773587498112bf177b87376c4d4a078b)

src/buffer.h
src/context.c
src/context.h
src/init.c
src/passwd.c
src/passwd.h
src/shared-api.c

index 704f51e..bc3116e 100644 (file)
@@ -28,7 +28,7 @@
 struct buffer {
        char    *buffer;        /* start address */
        size_t   length;        /* length in byte */
-       int              mapped;        /* is memory mapped */
+       int      mapped;        /* is memory mapped */
 };
 
 /*
index a0e1bb3..3b0fd5e 100644 (file)
@@ -22,8 +22,6 @@
  *
  */
 
-
-
 #define _GNU_SOURCE
 
 #ifdef HAVE_CONFIG_H
@@ -41,7 +39,6 @@
 #include "foreign.h"
 #include "context.h"
 
-
 uid_t get_uid(struct tzplatform_context *context)
 {
        uid_t result;
@@ -72,4 +69,3 @@ gid_t get_gid(struct tzplatform_context *context)
        return getgid();
 }
 #endif
-
index fdf0b69..f6c3fa4 100644 (file)
 #ifndef CONTEXT_H
 #define CONTEXT_H
 
+#include "foreign.h"
+#include "buffer.h"
+#include "tzplatform_variables.h"
+
 #ifndef HEAP_H
 #error "you should include heap.h"
 #endif
@@ -36,6 +40,12 @@ enum STATE { RESET = 0, ERROR, VALID };
 
 #define _USER_NOT_SET_ ((uid_t)-1)
 
+struct pw {
+       struct buffer buffer;
+       size_t pos, lengths[7];
+       const char *starts[7];
+};
+
 struct tzplatform_context {
 #ifndef NOT_MULTI_THREAD_SAFE
        pthread_mutex_t mutex;
@@ -44,6 +54,7 @@ struct tzplatform_context {
        uid_t user;
        struct heap heap;
        const char *values[_TZPLATFORM_VARIABLES_COUNT_];
+       struct pw pw;
 };
 
 uid_t get_uid(struct tzplatform_context *context);
index b431098..169f919 100644 (file)
@@ -186,7 +186,7 @@ static void foreignpw(struct reading *reading)
 
        if (n) {
                array[n] = NULL;
-               if (pw_get(&reading->context->heap, array) == 0) {
+               if (pw_get(reading->context, &reading->context->heap, array) == 0) {
 #if _FOREIGN_HAS_(HOME)
                        if (uid.set)
                                reading->dynvars[HOME] = uid.home;
index 325cc30..629664d 100644 (file)
 enum { iname, ipasswd, iuid, igid, icmt, idir, ishell };
 
 static const char pwfile[] = "/etc/passwd";
-static struct buffer buffer;
-static size_t pos, lengths[7];
-static const char *starts[7];
 
-#define is(s, i) (!strncmp(s, starts[i], lengths[i]) && !s[lengths[i]])
+#define is(s, i) (!strncmp(s, context->pw.starts[i], context->pw.lengths[i]) && !s[context->pw.lengths[i]])
 
 /* open the passwd file */
-static int oppw()
+static int oppw(struct tzplatform_context *context)
 {
-       pos = 0;
-       return buffer_create(&buffer, pwfile);
+       context->pw.pos = 0;
+       return buffer_create(&context->pw.buffer, pwfile);
 }
 
 /* close the passwd file */
-static void clpw()
+static void clpw(struct tzplatform_context *context)
 {
-       buffer_destroy(&buffer);
+       buffer_destroy(&context->pw.buffer);
 }
 
 /* read the passwd file */
-static int rdpw()
+static int rdpw(struct tzplatform_context *context)
 {
        int col = 0;
-       const char *head = buffer.buffer + pos;
-       const char *end = buffer.buffer + buffer.length;
+       struct pw *pw = &context->pw;
+       const char *head = pw->buffer.buffer + pw->pos;
+       const char *end = pw->buffer.buffer + pw->buffer.length;
        while (head != end) {
-               starts[col] = head;
+               pw->starts[col] = head;
                while (head != end && *head != ':' && *head != '\n') head++;
-               lengths[col] = head - starts[col];
+               pw->lengths[col] = head - pw->starts[col];
                col++;
                if (col == 7) {
                        if (head == end) {
-                               pos = head - buffer.buffer;
+                               pw->pos = head - pw->buffer.buffer;
                                return 1;
                        }
                        if (*head == '\n') {
                                head++;
-                               pos = head - buffer.buffer;
+                               pw->pos = head - pw->buffer.buffer;
                                return 1;
                        }
                        while (head != end && *head != '\n') head++;
@@ -93,31 +91,32 @@ static int rdpw()
                        }
                }
        }
-       pos = head - buffer.buffer;
+       pw->pos = head - pw->buffer.buffer;
        return 0;
 }
 
-int pw_get(struct heap *heap, struct pwget **items)
+int pw_get(struct tzplatform_context *context, struct heap *heap, struct pwget **items)
 {
        size_t user, home;
        int result;
        int i, n, s;
+       struct pw *pw = &context->pw;
 
        for (n = 0 ; items[n] != NULL ; n++)
                items[n]->set = 0;
 
-       result = oppw();
+       result = oppw(context);
        if (result == 0) {
                s = n;
-               while (s && rdpw()) {
+               while (s && rdpw(context)) {
                        user = home = HNULL;
                        for (i = 0 ; i < n ; i++) {
                                if (!items[i]->set && is(items[i]->id, iuid)) {
                                        if (user == HNULL) {
                                                user = heap_strndup(heap,
-                                                                                       starts[iname], lengths[iname]);
+                                                       pw->starts[iname], pw->lengths[iname]);
                                                home = heap_strndup(heap,
-                                                                                       starts[idir], lengths[idir]);
+                                                       pw->starts[idir], pw->lengths[idir]);
                                        }
                                        items[i]->set = 1;
                                        items[i]->user = user;
@@ -126,55 +125,57 @@ int pw_get(struct heap *heap, struct pwget **items)
                                }
                        }
                }
-               clpw();
+               clpw(context);
        }
        return result;
 }
 
-int pw_has_uid(uid_t uid)
+int pw_has_uid(struct tzplatform_context *context, uid_t uid)
 {
-       if (oppw() == 0) {
-               while (rdpw()) {
-                       if (lengths[iuid] && (int)uid == atoi(starts[iuid])) {
-                               clpw();
+       struct pw *pw = &context->pw;
+
+       if (oppw(context) == 0) {
+               while (rdpw(context)) {
+                       if (pw->lengths[iuid] && (int)uid == atoi(pw->starts[iuid])) {
+                               clpw(context);
                                return 1;
                        }
                }
-               clpw();
+               clpw(context);
        }
        return 0;
 }
 
-int pw_get_uid(const char *name, uid_t *uid)
+int pw_get_uid(struct tzplatform_context *context, const char *name, uid_t *uid)
 {
-       int result = oppw();
+       int result = oppw(context);
        if (result == 0) {
-               while (rdpw()) {
+               while (rdpw(context)) {
                        if (is(name, iname)) {
-                               *uid = (uid_t)atoi(starts[iuid]);
-                               clpw();
+                               *uid = (uid_t)atoi(context->pw.starts[iuid]);
+                               clpw(context);
                                return 0;
                        }
                }
-               clpw();
+               clpw(context);
                result = -1;
                errno = EEXIST;
        }
        return result;
 }
 
-int pw_get_gid(const char *name, gid_t *gid)
+int pw_get_gid(struct tzplatform_context *context, const char *name, gid_t *gid)
 {
-       int result = oppw();
+       int result = oppw(context);
        if (result == 0) {
-               while (rdpw()) {
+               while (rdpw(context)) {
                        if (is(name, iname)) {
-                               *gid = (gid_t)atoi(starts[igid]);
-                               clpw();
+                               *gid = (gid_t)atoi(context->pw.starts[igid]);
+                               clpw(context);
                                return 0;
                        }
                }
-               clpw();
+               clpw(context);
                result = -1;
                errno = EEXIST;
        }
index 475ee10..cd3d4e6 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef TIZEN_PLATFORM_WRAPPER_PASSWD_H
 #define TIZEN_PLATFORM_WRAPPER_PASSWD_H
 
+#include "context.h"
+
 struct pwget {
        int set;
        const char *id;
@@ -31,10 +33,10 @@ struct pwget {
        size_t home;
 };
 
-int pw_get(struct heap *heap, struct pwget **items);
-int pw_get_uid(const char *name, uid_t *uid);
-int pw_get_gid(const char *name, gid_t *gid);
-int pw_has_uid(uid_t uid);
+int pw_get(struct tzplatform_context *context, struct heap *heap, struct pwget **items);
+int pw_get_uid(struct tzplatform_context *context, const char *name, uid_t *uid);
+int pw_get_gid(struct tzplatform_context *context, const char *name, gid_t *gid);
+int pw_has_uid(struct tzplatform_context *context, uid_t uid);
 
 #endif
 
index 9688d8b..8997349 100644 (file)
 #include "heap.h"
 #include "scratch.h"
 #include "passwd.h"
-#include "foreign.h"
 #include "context.h"
 #include "hashing.h"
 #include "init.h"
 #include "shared-api.h"
 
-
 /* the global context */
 static struct tzplatform_context global_context = {
 #ifndef NOT_MULTI_THREAD_SAFE
@@ -185,7 +183,7 @@ int tzplatform_context_set_user(struct tzplatform_context *context, uid_t uid)
 {
        lock(context);
        if (context->user != uid) {
-               if (uid != _USER_NOT_SET_ && !pw_has_uid(uid)) {
+               if (uid != _USER_NOT_SET_ && !pw_has_uid(context, uid)) {
                        unlock(context);
                        return -1;
        }
@@ -358,7 +356,7 @@ uid_t _context_getuid_tzplatform_(int id, char signup[33], struct tzplatform_con
        result = (uid_t)-1;
        value = get_lock(id, context);
        if (value != NULL)
-               pw_get_uid(value, &result);
+               pw_get_uid(context, value, &result);
 
        unlock(context);
        return result;
@@ -378,7 +376,7 @@ gid_t _context_getgid_tzplatform_(int id, char signup[33], struct tzplatform_con
        result = (uid_t)-1;
        value = get_lock(id, context);
        if (value != NULL)
-               pw_get_gid(value, &result);
+               pw_get_gid(context, value, &result);
 
        unlock(context);
        return result;