Merge "Split the shared group data from the shared passwd data."
This commit is contained in:
commit
8597c2b3f2
@ -42,18 +42,44 @@
|
|||||||
#include "private/libc_logging.h"
|
#include "private/libc_logging.h"
|
||||||
#include "private/ThreadLocalBuffer.h"
|
#include "private/ThreadLocalBuffer.h"
|
||||||
|
|
||||||
GLOBAL_INIT_THREAD_LOCAL_BUFFER(stubs);
|
// POSIX seems to envisage an implementation where the <pwd.h> functions are
|
||||||
|
// implemented by brute-force searching with getpwent(3), and the <grp.h>
|
||||||
|
// functions are implemented similarly with getgrent(3). This means that it's
|
||||||
|
// okay for all the <grp.h> functions to share state, and all the <passwd.h>
|
||||||
|
// functions to share state, but <grp.h> functions can't clobber <passwd.h>
|
||||||
|
// functions' state and vice versa.
|
||||||
|
|
||||||
struct stubs_state_t {
|
GLOBAL_INIT_THREAD_LOCAL_BUFFER(group);
|
||||||
passwd passwd_;
|
|
||||||
|
struct group_state_t {
|
||||||
group group_;
|
group group_;
|
||||||
char* group_members_[2];
|
char* group_members_[2];
|
||||||
char app_name_buffer_[32];
|
|
||||||
char group_name_buffer_[32];
|
char group_name_buffer_[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
static group_state_t* __group_state() {
|
||||||
|
LOCAL_INIT_THREAD_LOCAL_BUFFER(group_state_t*, group, sizeof(group_state_t));
|
||||||
|
if (group_tls_buffer != NULL) {
|
||||||
|
memset(group_tls_buffer, 0, sizeof(group_state_t));
|
||||||
|
group_tls_buffer->group_.gr_mem = group_tls_buffer->group_members_;
|
||||||
|
}
|
||||||
|
return group_tls_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLOBAL_INIT_THREAD_LOCAL_BUFFER(passwd);
|
||||||
|
|
||||||
|
struct passwd_state_t {
|
||||||
|
passwd passwd_;
|
||||||
|
char app_name_buffer_[32];
|
||||||
char dir_buffer_[32];
|
char dir_buffer_[32];
|
||||||
char sh_buffer_[32];
|
char sh_buffer_[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static passwd_state_t* __passwd_state() {
|
||||||
|
LOCAL_INIT_THREAD_LOCAL_BUFFER(passwd_state_t*, passwd, sizeof(passwd_state_t));
|
||||||
|
return passwd_tls_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_getpw_r(int by_name, const char* name, uid_t uid,
|
static int do_getpw_r(int by_name, const char* name, uid_t uid,
|
||||||
passwd* dst, char* buf, size_t byte_count,
|
passwd* dst, char* buf, size_t byte_count,
|
||||||
passwd** result) {
|
passwd** result) {
|
||||||
@ -91,7 +117,7 @@ static int do_getpw_r(int by_name, const char* name, uid_t uid,
|
|||||||
|
|
||||||
// pw_passwd and pw_gecos are non-POSIX and unused (always NULL) in bionic.
|
// pw_passwd and pw_gecos are non-POSIX and unused (always NULL) in bionic.
|
||||||
dst->pw_passwd = NULL;
|
dst->pw_passwd = NULL;
|
||||||
#ifdef __LP64__
|
#if defined(__LP64__)
|
||||||
dst->pw_gecos = NULL;
|
dst->pw_gecos = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -113,17 +139,7 @@ int getpwuid_r(uid_t uid, passwd* pwd,
|
|||||||
return do_getpw_r(0, NULL, uid, pwd, buf, byte_count, result);
|
return do_getpw_r(0, NULL, uid, pwd, buf, byte_count, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static stubs_state_t* __stubs_state() {
|
static passwd* android_iinfo_to_passwd(passwd_state_t* state,
|
||||||
LOCAL_INIT_THREAD_LOCAL_BUFFER(stubs_state_t*, stubs, sizeof(stubs_state_t));
|
|
||||||
|
|
||||||
if (stubs_tls_buffer != NULL) {
|
|
||||||
memset(stubs_tls_buffer, 0, sizeof(stubs_state_t));
|
|
||||||
stubs_tls_buffer->group_.gr_mem = stubs_tls_buffer->group_members_;
|
|
||||||
}
|
|
||||||
return stubs_tls_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static passwd* android_iinfo_to_passwd(stubs_state_t* state,
|
|
||||||
const android_id_info* iinfo) {
|
const android_id_info* iinfo) {
|
||||||
snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
|
snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
|
||||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
|
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
|
||||||
@ -145,7 +161,7 @@ static group* android_iinfo_to_group(group* gr,
|
|||||||
return gr;
|
return gr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static passwd* android_id_to_passwd(stubs_state_t* state, unsigned id) {
|
static passwd* android_id_to_passwd(passwd_state_t* state, unsigned id) {
|
||||||
for (size_t n = 0; n < android_id_count; ++n) {
|
for (size_t n = 0; n < android_id_count; ++n) {
|
||||||
if (android_ids[n].aid == id) {
|
if (android_ids[n].aid == id) {
|
||||||
return android_iinfo_to_passwd(state, android_ids + n);
|
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) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static passwd* android_name_to_passwd(stubs_state_t* state, const char* name) {
|
static passwd* android_name_to_passwd(passwd_state_t* state, const char* name) {
|
||||||
for (size_t n = 0; n < android_id_count; ++n) {
|
for (size_t n = 0; n < android_id_count; ++n) {
|
||||||
if (!strcmp(android_ids[n].name, name)) {
|
if (!strcmp(android_ids[n].name, name)) {
|
||||||
return android_iinfo_to_passwd(state, android_ids + n);
|
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
|
|||||||
// AID_ISOLATED_START to AID_USER-1 -> u0_i1234
|
// AID_ISOLATED_START to AID_USER-1 -> u0_i1234
|
||||||
// AID_USER+ -> u1_radio, u1_a1234, u2_i1234, etc.
|
// AID_USER+ -> u1_radio, u1_a1234, u2_i1234, etc.
|
||||||
// returns a passwd structure (sets errno to ENOENT on failure).
|
// returns a passwd structure (sets errno to ENOENT on failure).
|
||||||
static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) {
|
static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) {
|
||||||
passwd* pw = &state->passwd_;
|
|
||||||
|
|
||||||
if (uid < AID_APP) {
|
if (uid < AID_APP) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -316,18 +330,18 @@ static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) {
|
|||||||
|
|
||||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
|
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
|
||||||
|
|
||||||
|
passwd* pw = &state->passwd_;
|
||||||
pw->pw_name = state->app_name_buffer_;
|
pw->pw_name = state->app_name_buffer_;
|
||||||
pw->pw_dir = state->dir_buffer_;
|
pw->pw_dir = state->dir_buffer_;
|
||||||
pw->pw_shell = state->sh_buffer_;
|
pw->pw_shell = state->sh_buffer_;
|
||||||
pw->pw_uid = uid;
|
pw->pw_uid = uid;
|
||||||
pw->pw_gid = uid;
|
pw->pw_gid = uid;
|
||||||
|
|
||||||
return pw;
|
return pw;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate a gid into the corresponding app_<gid>
|
// Translate a gid into the corresponding app_<gid>
|
||||||
// group structure (sets errno to ENOENT on failure).
|
// group structure (sets errno to ENOENT on failure).
|
||||||
static group* app_id_to_group(gid_t gid, stubs_state_t* state) {
|
static group* app_id_to_group(gid_t gid, group_state_t* state) {
|
||||||
if (gid < AID_APP) {
|
if (gid < AID_APP) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -339,13 +353,11 @@ static group* app_id_to_group(gid_t gid, stubs_state_t* state) {
|
|||||||
gr->gr_name = state->group_name_buffer_;
|
gr->gr_name = state->group_name_buffer_;
|
||||||
gr->gr_gid = gid;
|
gr->gr_gid = gid;
|
||||||
gr->gr_mem[0] = gr->gr_name;
|
gr->gr_mem[0] = gr->gr_name;
|
||||||
|
|
||||||
return gr;
|
return gr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
|
passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
|
||||||
stubs_state_t* state = __stubs_state();
|
passwd_state_t* state = __passwd_state();
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -358,7 +370,7 @@ passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
|
|||||||
}
|
}
|
||||||
|
|
||||||
passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
|
passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
|
||||||
stubs_state_t* state = __stubs_state();
|
passwd_state_t* state = __passwd_state();
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -386,7 +398,7 @@ char* getlogin() { // NOLINT: implementing bad function.
|
|||||||
}
|
}
|
||||||
|
|
||||||
group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
|
group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
|
||||||
stubs_state_t* state = __stubs_state();
|
group_state_t* state = __group_state();
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -399,7 +411,7 @@ group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
|
|||||||
}
|
}
|
||||||
|
|
||||||
group* getgrnam(const char* name) { // NOLINT: implementing bad function.
|
group* getgrnam(const char* name) { // NOLINT: implementing bad function.
|
||||||
stubs_state_t* state = __stubs_state();
|
group_state_t* state = __group_state();
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,8 @@ enum {
|
|||||||
* ttyname libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
* ttyname libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
||||||
* strerror libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
* strerror libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
||||||
* strsignal libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
* strsignal libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
||||||
* stubs libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
* passwd libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
||||||
|
* group libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
|
||||||
* _res_key libc
|
* _res_key libc
|
||||||
* je_thread_allocated_tsd jemalloc
|
* je_thread_allocated_tsd jemalloc
|
||||||
* je_arenas_tsd jemalloc
|
* je_arenas_tsd jemalloc
|
||||||
@ -95,7 +96,7 @@ enum {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LIBC_TLS_RESERVED_SLOTS 11
|
#define LIBC_TLS_RESERVED_SLOTS 12
|
||||||
|
|
||||||
#if defined(USE_JEMALLOC)
|
#if defined(USE_JEMALLOC)
|
||||||
/* jemalloc uses 5 keys for itself. */
|
/* jemalloc uses 5 keys for itself. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user