Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 382f5fb3 authored by Nick Kralevich's avatar Nick Kralevich Committed by Android Git Automerger
Browse files

am 748c546b: am c4db5ece: am 8e0c88ea: Merge "servicemanager: log pid and uid on selinux denial"

* commit '748c546b':
  servicemanager: log pid and uid on selinux denial
parents 05eb0e57 748c546b
Loading
Loading
Loading
Loading
+34 −16
Original line number Diff line number Diff line
@@ -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 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;
@@ -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
@@ -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;
    }

@@ -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;
@@ -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;
@@ -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;
}