Add preliminary OEM UID/GID support.
Until we implement full support for passwd/group files, add a simple
way to use the new OEM UID/GID range (5000-5999).
oem_XXX -> 5000 + XXX iff 0 <= XXX < 1000.
Bug: 23225475
Change-Id: If48b88135d5df538313414f747d6c4c63bf0a103
diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp
index 41c78bc..0340f0e 100644
--- a/libc/bionic/stubs.cpp
+++ b/libc/bionic/stubs.cpp
@@ -206,7 +206,7 @@
// u0_a1234 -> 0 * AID_USER + AID_APP + 1234
// u2_i1000 -> 2 * AID_USER + AID_ISOLATED_START + 1000
// u1_system -> 1 * AID_USER + android_ids['system']
-// returns 0 and sets errno to ENOENT in case of error
+// returns 0 and sets errno to ENOENT in case of error.
static id_t app_id_from_name(const char* name, bool is_group) {
char* end;
unsigned long userid;
@@ -312,6 +312,54 @@
}
}
+// Translate an OEM name to the corresponding user/group id.
+// oem_XXX -> AID_OEM_RESERVED_2_START + XXX, iff XXX is within range.
+static id_t oem_id_from_name(const char* name) {
+ unsigned int id;
+ if (sscanf(name, "oem_%u", &id) != 1) {
+ return 0;
+ }
+ // Check OEM id is within range.
+ if (id > (AID_OEM_RESERVED_2_END - AID_OEM_RESERVED_2_START)) {
+ return 0;
+ }
+ return AID_OEM_RESERVED_2_START + static_cast<id_t>(id);
+}
+
+static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
+ if (uid < AID_OEM_RESERVED_2_START || uid > AID_OEM_RESERVED_2_END) {
+ return NULL;
+ }
+
+ snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u",
+ uid - AID_OEM_RESERVED_2_START);
+ snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
+ snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
+
+ passwd* pw = &state->passwd_;
+ pw->pw_name = state->name_buffer_;
+ pw->pw_dir = state->dir_buffer_;
+ pw->pw_shell = state->sh_buffer_;
+ pw->pw_uid = uid;
+ pw->pw_gid = uid;
+ return pw;
+}
+
+static group* oem_id_to_group(gid_t gid, group_state_t* state) {
+ if (gid < AID_OEM_RESERVED_2_START || gid > AID_OEM_RESERVED_2_END) {
+ return NULL;
+ }
+
+ snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
+ "oem_%u", gid - AID_OEM_RESERVED_2_START);
+
+ group* gr = &state->group_;
+ gr->gr_name = state->group_name_buffer_;
+ gr->gr_gid = gid;
+ gr->gr_mem[0] = gr->gr_name;
+ return gr;
+}
+
// Translate a uid into the corresponding name.
// 0 to AID_APP-1 -> "system", "radio", etc.
// AID_APP to AID_ISOLATED_START-1 -> u0_a1234
@@ -371,6 +419,11 @@
if (pw != NULL) {
return pw;
}
+ // Handle OEM range.
+ pw = oem_id_to_passwd(uid, state);
+ if (pw != NULL) {
+ return pw;
+ }
return app_id_to_passwd(uid, state);
}
@@ -384,6 +437,11 @@
if (pw != NULL) {
return pw;
}
+ // Handle OEM range.
+ pw = oem_id_to_passwd(oem_id_from_name(login), state);
+ if (pw != NULL) {
+ return pw;
+ }
return app_id_to_passwd(app_id_from_name(login, false), state);
}
@@ -407,6 +465,11 @@
if (grp != NULL) {
return grp;
}
+ // Handle OEM range.
+ grp = oem_id_to_group(gid, state);
+ if (grp != NULL) {
+ return grp;
+ }
return app_id_to_group(gid, state);
}
@@ -423,6 +486,11 @@
if (grp != NULL) {
return grp;
}
+ // Handle OEM range.
+ grp = oem_id_to_group(oem_id_from_name(name), state);
+ if (grp != NULL) {
+ return grp;
+ }
return app_id_to_group(app_id_from_name(name, true), state);
}