am c4db5ece: am 8e0c88ea: Merge "servicemanager: log pid and uid on selinux denial"
* commit 'c4db5ece1b34ada975041c167215d41a58f788ca':
servicemanager: log pid and uid on selinux denial
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 7fa9a39..8596f96 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -23,6 +23,12 @@
#include <cutils/log.h>
#endif
+struct audit_data {
+ pid_t pid;
+ uid_t uid;
+ const char *name;
+};
+
const char *str8(const uint16_t *x, size_t x_len)
{
static char buf[128];
@@ -56,34 +62,39 @@
static char *service_manager_context;
static struct selabel_handle* sehandle;
-static bool check_mac_perms(pid_t spid, const char *tctx, const char *perm, const char *name)
+static bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name)
{
char *sctx = NULL;
const char *class = "service_manager";
bool allowed;
+ struct audit_data ad;
if (getpidcon(spid, &sctx) < 0) {
ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid);
return false;
}
- int result = selinux_check_access(sctx, tctx, class, perm, (void *) name);
+ ad.pid = spid;
+ ad.uid = uid;
+ ad.name = name;
+
+ int result = selinux_check_access(sctx, tctx, class, perm, (void *) &ad);
allowed = (result == 0);
freecon(sctx);
return allowed;
}
-static bool check_mac_perms_from_getcon(pid_t spid, const char *perm)
+static bool check_mac_perms_from_getcon(pid_t spid, uid_t uid, const char *perm)
{
if (selinux_enabled <= 0) {
return true;
}
- return check_mac_perms(spid, service_manager_context, perm, NULL);
+ return check_mac_perms(spid, uid, service_manager_context, perm, NULL);
}
-static bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char *name)
+static bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name)
{
bool allowed;
char *tctx = NULL;
@@ -102,27 +113,27 @@
return false;
}
- allowed = check_mac_perms(spid, tctx, perm, name);
+ allowed = check_mac_perms(spid, uid, tctx, perm, name);
freecon(tctx);
return allowed;
}
-static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid)
+static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
{
const char *perm = "add";
- return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0;
+ return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
}
-static int svc_can_list(pid_t spid)
+static int svc_can_list(pid_t spid, uid_t uid)
{
const char *perm = "list";
- return check_mac_perms_from_getcon(spid, perm) ? 1 : 0;
+ return check_mac_perms_from_getcon(spid, uid, perm) ? 1 : 0;
}
-static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid)
+static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
{
const char *perm = "find";
- return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0;
+ return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
}
struct svcinfo
@@ -184,7 +195,7 @@
}
}
- if (!svc_can_find(s, len, spid)) {
+ if (!svc_can_find(s, len, spid, uid)) {
return 0;
}
@@ -204,7 +215,7 @@
if (!handle || (len == 0) || (len > 127))
return -1;
- if (!svc_can_register(s, len, spid)) {
+ if (!svc_can_register(s, len, spid, uid)) {
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
str8(s, len), handle, uid);
return -1;
@@ -314,7 +325,7 @@
case SVC_MGR_LIST_SERVICES: {
uint32_t n = bio_get_uint32(msg);
- if (!svc_can_list(txn->sender_pid)) {
+ if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
txn->sender_euid);
return -1;
@@ -340,7 +351,14 @@
static int audit_callback(void *data, security_class_t cls, char *buf, size_t len)
{
- snprintf(buf, len, "service=%s", !data ? "NULL" : (char *)data);
+ struct audit_data *ad = (struct audit_data *)data;
+
+ if (!ad || !ad->name) {
+ ALOGE("No service manager audit data");
+ return 0;
+ }
+
+ snprintf(buf, len, "service=%s pid=%d uid=%d", ad->name, ad->pid, ad->uid);
return 0;
}