diff options
author | Elliott Hughes | 2014-12-18 17:12:44 -0600 |
---|---|---|
committer | Gerrit Code Review | 2014-12-18 17:12:45 -0600 |
commit | 8597c2b3f2ac3df9abe30378cdd3ecd559d995e7 (patch) | |
tree | 4f5508a7c9336b06094e8eb509015d5a4645bcfb /libc | |
parent | a9c940a69a5ad01a92620594d41e462c5d46186e (diff) | |
parent | 7874f1d7182d80eb72c699eaa9ab8cc4cfec95ab (diff) | |
download | platform-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.cpp | 82 | ||||
-rw-r--r-- | libc/private/bionic_tls.h | 5 |
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 | ||
45 | GLOBAL_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 | ||
47 | struct stubs_state_t { | 52 | GLOBAL_INIT_THREAD_LOCAL_BUFFER(group); |
48 | passwd passwd_; | 53 | |
54 | struct 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 | |||
60 | static 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 | |||
69 | GLOBAL_INIT_THREAD_LOCAL_BUFFER(passwd); | ||
70 | |||
71 | struct 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 | ||
78 | static 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 | |||
57 | static int do_getpw_r(int by_name, const char* name, uid_t uid, | 83 | static 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 | ||
116 | static stubs_state_t* __stubs_state() { | 142 | static 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 | |||
126 | static 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 | ||
148 | static passwd* android_id_to_passwd(stubs_state_t* state, unsigned id) { | 164 | static 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 | ||
157 | static passwd* android_name_to_passwd(stubs_state_t* state, const char* name) { | 173 | static 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). |
300 | static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) { | 316 | static 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). |
330 | static group* app_id_to_group(gid_t gid, stubs_state_t* state) { | 344 | static 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 | |||
347 | passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function. | 359 | passwd* 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 | ||
360 | passwd* getpwnam(const char* login) { // NOLINT: implementing bad function. | 372 | passwd* 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. |
374 | int getgrouplist(const char* /*user*/, gid_t group, gid_t* groups, int* ngroups) { | 386 | int 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 | ||
383 | char* getlogin() { // NOLINT: implementing bad function. | 395 | char* getlogin() { // NOLINT: implementing bad function. |
@@ -386,7 +398,7 @@ char* getlogin() { // NOLINT: implementing bad function. | |||
386 | } | 398 | } |
387 | 399 | ||
388 | group* getgrgid(gid_t gid) { // NOLINT: implementing bad function. | 400 | group* 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 | ||
401 | group* getgrnam(const char* name) { // NOLINT: implementing bad function. | 413 | group* 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. */ |