Loading cmds/servicemanager/service_manager.c +34 −16 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -56,34 +62,39 @@ static int selinux_enabled; 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; Loading @@ -102,27 +113,27 @@ static bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char 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 Loading Loading @@ -184,7 +195,7 @@ uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, } } if (!svc_can_find(s, len, spid)) { if (!svc_can_find(s, len, spid, uid)) { return 0; } Loading @@ -204,7 +215,7 @@ int do_add_service(struct binder_state *bs, 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; Loading Loading @@ -314,7 +325,7 @@ int svcmgr_handler(struct binder_state *bs, 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; Loading @@ -340,7 +351,14 @@ int svcmgr_handler(struct binder_state *bs, 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; } Loading Loading
cmds/servicemanager/service_manager.c +34 −16 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -56,34 +62,39 @@ static int selinux_enabled; 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; Loading @@ -102,27 +113,27 @@ static bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char 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 Loading Loading @@ -184,7 +195,7 @@ uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, } } if (!svc_can_find(s, len, spid)) { if (!svc_can_find(s, len, spid, uid)) { return 0; } Loading @@ -204,7 +215,7 @@ int do_add_service(struct binder_state *bs, 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; Loading Loading @@ -314,7 +325,7 @@ int svcmgr_handler(struct binder_state *bs, 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; Loading @@ -340,7 +351,14 @@ int svcmgr_handler(struct binder_state *bs, 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; } Loading