Get SID from kernel.
Bug: 121035042
Test: boot
Change-Id: I0941e5a13305859e1b913ec4451173e5408c808e
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 79cd6b5..ca004e9 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -61,14 +61,14 @@
static char *service_manager_context;
static struct selabel_handle* sehandle;
-static bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name)
+static bool check_mac_perms(pid_t spid, const char* sid, uid_t uid, const char *tctx, const char *perm, const char *name)
{
- char *sctx = NULL;
+ char *lookup_sid = NULL;
const char *class = "service_manager";
bool allowed;
struct audit_data ad;
- if (getpidcon(spid, &sctx) < 0) {
+ if (sid == NULL && getpidcon(spid, &lookup_sid) < 0) {
ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid);
return false;
}
@@ -77,19 +77,25 @@
ad.uid = uid;
ad.name = name;
- int result = selinux_check_access(sctx, tctx, class, perm, (void *) &ad);
+#ifndef VENDORSERVICEMANAGER
+ if (sid == NULL) {
+ android_errorWriteLog(0x534e4554, "121035042");
+ }
+#endif
+
+ int result = selinux_check_access(sid ? sid : lookup_sid, tctx, class, perm, (void *) &ad);
allowed = (result == 0);
- freecon(sctx);
+ freecon(lookup_sid);
return allowed;
}
-static bool check_mac_perms_from_getcon(pid_t spid, uid_t uid, const char *perm)
+static bool check_mac_perms_from_getcon(pid_t spid, const char* sid, uid_t uid, const char *perm)
{
- return check_mac_perms(spid, uid, service_manager_context, perm, NULL);
+ return check_mac_perms(spid, sid, uid, service_manager_context, perm, NULL);
}
-static bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name)
+static bool check_mac_perms_from_lookup(pid_t spid, const char* sid, uid_t uid, const char *perm, const char *name)
{
bool allowed;
char *tctx = NULL;
@@ -104,12 +110,12 @@
return false;
}
- allowed = check_mac_perms(spid, uid, tctx, perm, name);
+ allowed = check_mac_perms(spid, sid, uid, tctx, perm, name);
freecon(tctx);
return allowed;
}
-static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
+static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, const char* sid, uid_t uid)
{
const char *perm = "add";
@@ -117,19 +123,19 @@
return 0; /* Don't allow apps to register services */
}
- return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
+ return check_mac_perms_from_lookup(spid, sid, uid, perm, str8(name, name_len)) ? 1 : 0;
}
-static int svc_can_list(pid_t spid, uid_t uid)
+static int svc_can_list(pid_t spid, const char* sid, uid_t uid)
{
const char *perm = "list";
- return check_mac_perms_from_getcon(spid, uid, perm) ? 1 : 0;
+ return check_mac_perms_from_getcon(spid, sid, uid, perm) ? 1 : 0;
}
-static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
+static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, const char* sid, uid_t uid)
{
const char *perm = "find";
- return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
+ return check_mac_perms_from_lookup(spid, sid, uid, perm, str8(name, name_len)) ? 1 : 0;
}
struct svcinfo
@@ -175,7 +181,7 @@
};
-uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
+uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid, const char* sid)
{
struct svcinfo *si = find_svc(s, len);
@@ -192,7 +198,7 @@
}
}
- if (!svc_can_find(s, len, spid, uid)) {
+ if (!svc_can_find(s, len, spid, sid, uid)) {
return 0;
}
@@ -200,7 +206,7 @@
}
int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle,
- uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) {
+ uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid, const char* sid) {
struct svcinfo *si;
//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
@@ -209,7 +215,7 @@
if (!handle || (len == 0) || (len > 127))
return -1;
- if (!svc_can_register(s, len, spid, uid)) {
+ if (!svc_can_register(s, len, spid, sid, uid)) {
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
str8(s, len), handle, uid);
return -1;
@@ -248,7 +254,7 @@
}
int svcmgr_handler(struct binder_state *bs,
- struct binder_transaction_data *txn,
+ struct binder_transaction_data_secctx *txn_secctx,
struct binder_io *msg,
struct binder_io *reply)
{
@@ -260,6 +266,8 @@
int allow_isolated;
uint32_t dumpsys_priority;
+ struct binder_transaction_data *txn = &txn_secctx->transaction_data;
+
//ALOGI("target=%p code=%d pid=%d uid=%d\n",
// (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
@@ -305,7 +313,8 @@
if (s == NULL) {
return -1;
}
- handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
+ handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid,
+ (const char*) txn_secctx->secctx);
if (!handle)
break;
bio_put_ref(reply, handle);
@@ -320,7 +329,7 @@
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
dumpsys_priority = bio_get_uint32(msg);
if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
- txn->sender_pid))
+ txn->sender_pid, (const char*) txn_secctx->secctx))
return -1;
break;
@@ -328,7 +337,7 @@
uint32_t n = bio_get_uint32(msg);
uint32_t req_dumpsys_priority = bio_get_uint32(msg);
- if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
+ if (!svc_can_list(txn->sender_pid, (const char*) txn_secctx->secctx, txn->sender_euid)) {
ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
txn->sender_euid);
return -1;