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

Commit d7aea443 authored by William Roberts's avatar William Roberts
Browse files

property_service: log pid,uid and gid of setprop client



When auditing setprop denials, it is often unclear of who the process is
in a multi-process domain. To help identify the invoker, log the pid, uid,
and gid of the caller.

Before:
avc:  denied  { set } for property=wifi.xxx ...

After:
avc:  denied  { set } for property=wifi.xxx pid=30691 uid=123 gid=345 ...

Change-Id: I5cdcb3d18fbd52e0987b5e1497b9f6620c6c742a
Signed-off-by: default avatarWilliam Roberts <william.c.roberts@intel.com>
parent bd4f52b2
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -467,7 +467,16 @@ int selinux_reload_policy(void)
}

static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_t len) {
    snprintf(buf, len, "property=%s", !data ? "NULL" : (char *)data);

    property_audit_data *d = reinterpret_cast<property_audit_data*>(data);

    if (!d || !d->name || !d->cr) {
        ERROR("audit_callback invoked with null data arguments!");
        return 0;
    }

    snprintf(buf, len, "property=%s pid=%d uid=%d gid=%d", d->name,
            d->cr->pid, d->cr->uid, d->cr->gid);
    return 0;
}

+12 −8
Original line number Diff line number Diff line
@@ -90,10 +90,11 @@ void property_init() {
    }
}

static int check_mac_perms(const char *name, char *sctx)
static int check_mac_perms(const char *name, char *sctx, struct ucred *cr)
{
    char *tctx = NULL;
    int result = 0;
    property_audit_data audit_data;

    if (!sctx)
        goto err;
@@ -104,7 +105,10 @@ static int check_mac_perms(const char *name, char *sctx)
    if (selabel_lookup(sehandle_prop, &tctx, name, 1) != 0)
        goto err;

    if (selinux_check_access(sctx, tctx, "property_service", "set", (void*) name) == 0)
    audit_data.name = name;
    audit_data.cr = cr;

    if (selinux_check_access(sctx, tctx, "property_service", "set", reinterpret_cast<void*>(&audit_data)) == 0)
        result = 1;

    freecon(tctx);
@@ -112,7 +116,7 @@ static int check_mac_perms(const char *name, char *sctx)
    return result;
}

static int check_control_mac_perms(const char *name, char *sctx)
static int check_control_mac_perms(const char *name, char *sctx, struct ucred *cr)
{
    /*
     *  Create a name prefix out of ctl.<service name>
@@ -126,19 +130,19 @@ static int check_control_mac_perms(const char *name, char *sctx)
    if (ret < 0 || (size_t) ret >= sizeof(ctl_name))
        return 0;

    return check_mac_perms(ctl_name, sctx);
    return check_mac_perms(ctl_name, sctx, cr);
}

/*
 * Checks permissions for setting system properties.
 * Returns 1 if uid allowed, 0 otherwise.
 */
static int check_perms(const char *name, char *sctx)
static int check_perms(const char *name, char *sctx, struct ucred *cr)
{
    if(!strncmp(name, "ro.", 3))
        name +=3;

    return check_mac_perms(name, sctx);
    return check_mac_perms(name, sctx, cr);
}

std::string property_get(const char* name) {
@@ -314,14 +318,14 @@ static void handle_property_set_fd()
            // Keep the old close-socket-early behavior when handling
            // ctl.* properties.
            close(s);
            if (check_control_mac_perms(msg.value, source_ctx)) {
            if (check_control_mac_perms(msg.value, source_ctx, &cr)) {
                handle_control_message((char*) msg.name + 4, (char*) msg.value);
            } else {
                ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d\n",
                        msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);
            }
        } else {
            if (check_perms(msg.name, source_ctx)) {
            if (check_perms(msg.name, source_ctx, &cr)) {
                property_set((char*) msg.name, (char*) msg.value);
            } else {
                ERROR("sys_prop: permission denied uid:%d  name:%s\n",
+6 −0
Original line number Diff line number Diff line
@@ -18,9 +18,15 @@
#define _INIT_PROPERTY_H

#include <stddef.h>
#include <sys/socket.h>
#include <sys/system_properties.h>
#include <string>

struct property_audit_data {
    ucred *cr;
    const char* name;
};

extern void property_init(void);
extern void property_load_boot_defaults(void);
extern void load_persist_props(void);