aboutsummaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
authorElliott Hughes2014-12-18 17:12:44 -0600
committerGerrit Code Review2014-12-18 17:12:45 -0600
commit8597c2b3f2ac3df9abe30378cdd3ecd559d995e7 (patch)
tree4f5508a7c9336b06094e8eb509015d5a4645bcfb /libc
parenta9c940a69a5ad01a92620594d41e462c5d46186e (diff)
parent7874f1d7182d80eb72c699eaa9ab8cc4cfec95ab (diff)
downloadplatform-bionic-8597c2b3f2ac3df9abe30378cdd3ecd559d995e7.tar.gz
platform-bionic-8597c2b3f2ac3df9abe30378cdd3ecd559d995e7.tar.xz
platform-bionic-8597c2b3f2ac3df9abe30378cdd3ecd559d995e7.zip
Merge "Split the shared group data from the shared passwd data."
Diffstat (limited to 'libc')
-rw-r--r--libc/bionic/stubs.cpp82
-rw-r--r--libc/private/bionic_tls.h5
2 files changed, 50 insertions, 37 deletions
diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp
index 88e5ac5e..ab679355 100644
--- a/libc/bionic/stubs.cpp
+++ b/libc/bionic/stubs.cpp
@@ -42,18 +42,44 @@
42#include "private/libc_logging.h" 42#include "private/libc_logging.h"
43#include "private/ThreadLocalBuffer.h" 43#include "private/ThreadLocalBuffer.h"
44 44
45GLOBAL_INIT_THREAD_LOCAL_BUFFER(stubs); 45// POSIX seems to envisage an implementation where the <pwd.h> functions are
46// implemented by brute-force searching with getpwent(3), and the <grp.h>
47// functions are implemented similarly with getgrent(3). This means that it's
48// okay for all the <grp.h> functions to share state, and all the <passwd.h>
49// functions to share state, but <grp.h> functions can't clobber <passwd.h>
50// functions' state and vice versa.
46 51
47struct stubs_state_t { 52GLOBAL_INIT_THREAD_LOCAL_BUFFER(group);
48 passwd passwd_; 53
54struct group_state_t {
49 group group_; 55 group group_;
50 char* group_members_[2]; 56 char* group_members_[2];
51 char app_name_buffer_[32];
52 char group_name_buffer_[32]; 57 char group_name_buffer_[32];
58};
59
60static group_state_t* __group_state() {
61 LOCAL_INIT_THREAD_LOCAL_BUFFER(group_state_t*, group, sizeof(group_state_t));
62 if (group_tls_buffer != NULL) {
63 memset(group_tls_buffer, 0, sizeof(group_state_t));
64 group_tls_buffer->group_.gr_mem = group_tls_buffer->group_members_;
65 }
66 return group_tls_buffer;
67}
68
69GLOBAL_INIT_THREAD_LOCAL_BUFFER(passwd);
70
71struct passwd_state_t {
72 passwd passwd_;
73 char app_name_buffer_[32];
53 char dir_buffer_[32]; 74 char dir_buffer_[32];
54 char sh_buffer_[32]; 75 char sh_buffer_[32];
55}; 76};
56 77
78static passwd_state_t* __passwd_state() {
79 LOCAL_INIT_THREAD_LOCAL_BUFFER(passwd_state_t*, passwd, sizeof(passwd_state_t));
80 return passwd_tls_buffer;
81}
82
57static int do_getpw_r(int by_name, const char* name, uid_t uid, 83static int do_getpw_r(int by_name, const char* name, uid_t uid,
58 passwd* dst, char* buf, size_t byte_count, 84 passwd* dst, char* buf, size_t byte_count,
59 passwd** result) { 85 passwd** result) {
@@ -91,7 +117,7 @@ static int do_getpw_r(int by_name, const char* name, uid_t uid,
91 117
92 // pw_passwd and pw_gecos are non-POSIX and unused (always NULL) in bionic. 118 // pw_passwd and pw_gecos are non-POSIX and unused (always NULL) in bionic.
93 dst->pw_passwd = NULL; 119 dst->pw_passwd = NULL;
94#ifdef __LP64__ 120#if defined(__LP64__)
95 dst->pw_gecos = NULL; 121 dst->pw_gecos = NULL;
96#endif 122#endif
97 123
@@ -113,17 +139,7 @@ int getpwuid_r(uid_t uid, passwd* pwd,
113 return do_getpw_r(0, NULL, uid, pwd, buf, byte_count, result); 139 return do_getpw_r(0, NULL, uid, pwd, buf, byte_count, result);
114} 140}
115 141
116static stubs_state_t* __stubs_state() { 142static passwd* android_iinfo_to_passwd(passwd_state_t* state,
117 LOCAL_INIT_THREAD_LOCAL_BUFFER(stubs_state_t*, stubs, sizeof(stubs_state_t));
118
119 if (stubs_tls_buffer != NULL) {
120 memset(stubs_tls_buffer, 0, sizeof(stubs_state_t));
121 stubs_tls_buffer->group_.gr_mem = stubs_tls_buffer->group_members_;
122 }
123 return stubs_tls_buffer;
124}
125
126static passwd* android_iinfo_to_passwd(stubs_state_t* state,
127 const android_id_info* iinfo) { 143 const android_id_info* iinfo) {
128 snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/"); 144 snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
129 snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh"); 145 snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
@@ -145,7 +161,7 @@ static group* android_iinfo_to_group(group* gr,
145 return gr; 161 return gr;
146} 162}
147 163
148static passwd* android_id_to_passwd(stubs_state_t* state, unsigned id) { 164static passwd* android_id_to_passwd(passwd_state_t* state, unsigned id) {
149 for (size_t n = 0; n < android_id_count; ++n) { 165 for (size_t n = 0; n < android_id_count; ++n) {
150 if (android_ids[n].aid == id) { 166 if (android_ids[n].aid == id) {
151 return android_iinfo_to_passwd(state, android_ids + n); 167 return android_iinfo_to_passwd(state, android_ids + n);
@@ -154,7 +170,7 @@ static passwd* android_id_to_passwd(stubs_state_t* state, unsigned id) {
154 return NULL; 170 return NULL;
155} 171}
156 172
157static passwd* android_name_to_passwd(stubs_state_t* state, const char* name) { 173static passwd* android_name_to_passwd(passwd_state_t* state, const char* name) {
158 for (size_t n = 0; n < android_id_count; ++n) { 174 for (size_t n = 0; n < android_id_count; ++n) {
159 if (!strcmp(android_ids[n].name, name)) { 175 if (!strcmp(android_ids[n].name, name)) {
160 return android_iinfo_to_passwd(state, android_ids + n); 176 return android_iinfo_to_passwd(state, android_ids + n);
@@ -297,9 +313,7 @@ static void print_app_name_from_gid(const gid_t gid, char* buffer, const int buf
297// AID_ISOLATED_START to AID_USER-1 -> u0_i1234 313// AID_ISOLATED_START to AID_USER-1 -> u0_i1234
298// AID_USER+ -> u1_radio, u1_a1234, u2_i1234, etc. 314// AID_USER+ -> u1_radio, u1_a1234, u2_i1234, etc.
299// returns a passwd structure (sets errno to ENOENT on failure). 315// returns a passwd structure (sets errno to ENOENT on failure).
300static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) { 316static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) {
301 passwd* pw = &state->passwd_;
302
303 if (uid < AID_APP) { 317 if (uid < AID_APP) {
304 errno = ENOENT; 318 errno = ENOENT;
305 return NULL; 319 return NULL;
@@ -316,18 +330,18 @@ static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) {
316 330
317 snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh"); 331 snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
318 332
333 passwd* pw = &state->passwd_;
319 pw->pw_name = state->app_name_buffer_; 334 pw->pw_name = state->app_name_buffer_;
320 pw->pw_dir = state->dir_buffer_; 335 pw->pw_dir = state->dir_buffer_;
321 pw->pw_shell = state->sh_buffer_; 336 pw->pw_shell = state->sh_buffer_;
322 pw->pw_uid = uid; 337 pw->pw_uid = uid;
323 pw->pw_gid = uid; 338 pw->pw_gid = uid;
324
325 return pw; 339 return pw;
326} 340}
327 341
328// Translate a gid into the corresponding app_<gid> 342// Translate a gid into the corresponding app_<gid>
329// group structure (sets errno to ENOENT on failure). 343// group structure (sets errno to ENOENT on failure).
330static group* app_id_to_group(gid_t gid, stubs_state_t* state) { 344static group* app_id_to_group(gid_t gid, group_state_t* state) {
331 if (gid < AID_APP) { 345 if (gid < AID_APP) {
332 errno = ENOENT; 346 errno = ENOENT;
333 return NULL; 347 return NULL;
@@ -339,13 +353,11 @@ static group* app_id_to_group(gid_t gid, stubs_state_t* state) {
339 gr->gr_name = state->group_name_buffer_; 353 gr->gr_name = state->group_name_buffer_;
340 gr->gr_gid = gid; 354 gr->gr_gid = gid;
341 gr->gr_mem[0] = gr->gr_name; 355 gr->gr_mem[0] = gr->gr_name;
342
343 return gr; 356 return gr;
344} 357}
345 358
346
347passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function. 359passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
348 stubs_state_t* state = __stubs_state(); 360 passwd_state_t* state = __passwd_state();
349 if (state == NULL) { 361 if (state == NULL) {
350 return NULL; 362 return NULL;
351 } 363 }
@@ -358,7 +370,7 @@ passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
358} 370}
359 371
360passwd* getpwnam(const char* login) { // NOLINT: implementing bad function. 372passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
361 stubs_state_t* state = __stubs_state(); 373 passwd_state_t* state = __passwd_state();
362 if (state == NULL) { 374 if (state == NULL) {
363 return NULL; 375 return NULL;
364 } 376 }
@@ -372,12 +384,12 @@ passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
372 384
373// All users are in just one group, the one passed in. 385// All users are in just one group, the one passed in.
374int getgrouplist(const char* /*user*/, gid_t group, gid_t* groups, int* ngroups) { 386int getgrouplist(const char* /*user*/, gid_t group, gid_t* groups, int* ngroups) {
375 if (*ngroups < 1) { 387 if (*ngroups < 1) {
376 *ngroups = 1; 388 *ngroups = 1;
377 return -1; 389 return -1;
378 } 390 }
379 groups[0] = group; 391 groups[0] = group;
380 return (*ngroups = 1); 392 return (*ngroups = 1);
381} 393}
382 394
383char* getlogin() { // NOLINT: implementing bad function. 395char* getlogin() { // NOLINT: implementing bad function.
@@ -386,7 +398,7 @@ char* getlogin() { // NOLINT: implementing bad function.
386} 398}
387 399
388group* getgrgid(gid_t gid) { // NOLINT: implementing bad function. 400group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
389 stubs_state_t* state = __stubs_state(); 401 group_state_t* state = __group_state();
390 if (state == NULL) { 402 if (state == NULL) {
391 return NULL; 403 return NULL;
392 } 404 }
@@ -399,7 +411,7 @@ group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
399} 411}
400 412
401group* getgrnam(const char* name) { // NOLINT: implementing bad function. 413group* getgrnam(const char* name) { // NOLINT: implementing bad function.
402 stubs_state_t* state = __stubs_state(); 414 group_state_t* state = __group_state();
403 if (state == NULL) { 415 if (state == NULL) {
404 return NULL; 416 return NULL;
405 } 417 }
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 4a351668..944f9579 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -85,7 +85,8 @@ enum {
85 * ttyname libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER) 85 * ttyname libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
86 * strerror libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER) 86 * strerror libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
87 * strsignal libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER) 87 * strsignal libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
88 * stubs libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER) 88 * passwd libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
89 * group libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
89 * _res_key libc 90 * _res_key libc
90 * je_thread_allocated_tsd jemalloc 91 * je_thread_allocated_tsd jemalloc
91 * je_arenas_tsd jemalloc 92 * je_arenas_tsd jemalloc
@@ -95,7 +96,7 @@ enum {
95 * 96 *
96 */ 97 */
97 98
98#define LIBC_TLS_RESERVED_SLOTS 11 99#define LIBC_TLS_RESERVED_SLOTS 12
99 100
100#if defined(USE_JEMALLOC) 101#if defined(USE_JEMALLOC)
101/* jemalloc uses 5 keys for itself. */ 102/* jemalloc uses 5 keys for itself. */