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

Commit 2fb90dc8 authored by Nick Kralevich's avatar Nick Kralevich Committed by Gerrit Code Review
Browse files

Merge changes from topic 'userspace-audit'

* changes:
  debuggerd: audit pid, uid and gid on SE Linux denial
  property_service: log pid,uid and gid of setprop client
parents 4b2d6dd3 46857393
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -130,31 +130,44 @@ static const char *debuggerd_perms[] = {
  "dump_backtrace"
};

static bool selinux_action_allowed(int s, pid_t tid, debugger_action_t action)
static int audit_callback(void* data, security_class_t /* cls */, char* buf, size_t len)
{
    struct debugger_request_t* req = reinterpret_cast<debugger_request_t*>(data);

    if (!req) {
        ALOGE("No debuggerd request audit data");
        return 0;
    }

    snprintf(buf, len, "pid=%d uid=%d gid=%d", req->pid, req->uid, req->gid);
    return 0;
}

static bool selinux_action_allowed(int s, debugger_request_t* request)
{
  char *scon = NULL, *tcon = NULL;
  const char *tclass = "debuggerd";
  const char *perm;
  bool allowed = false;

  if (action <= 0 || action >= (sizeof(debuggerd_perms)/sizeof(debuggerd_perms[0]))) {
    ALOGE("SELinux:  No permission defined for debugger action %d", action);
  if (request->action <= 0 || request->action >= (sizeof(debuggerd_perms)/sizeof(debuggerd_perms[0]))) {
    ALOGE("SELinux:  No permission defined for debugger action %d", request->action);
    return false;
  }

  perm = debuggerd_perms[action];
  perm = debuggerd_perms[request->action];

  if (getpeercon(s, &scon) < 0) {
    ALOGE("Cannot get peer context from socket\n");
    goto out;
  }

  if (getpidcon(tid, &tcon) < 0) {
    ALOGE("Cannot get context for tid %d\n", tid);
  if (getpidcon(request->tid, &tcon) < 0) {
    ALOGE("Cannot get context for tid %d\n", request->tid);
    goto out;
  }

  allowed = (selinux_check_access(scon, tcon, tclass, perm, NULL) == 0);
  allowed = (selinux_check_access(scon, tcon, tclass, perm, reinterpret_cast<void*>(request)) == 0);

out:
   freecon(scon);
@@ -225,7 +238,7 @@ static int read_request(int fd, debugger_request_t* out_request) {
      return -1;
    }

    if (!selinux_action_allowed(fd, out_request->tid, out_request->action))
    if (!selinux_action_allowed(fd, out_request))
      return -1;
  } else {
    // No one else is allowed to dump arbitrary processes.
@@ -566,6 +579,8 @@ static void usage() {
int main(int argc, char** argv) {
  union selinux_callback cb;
  if (argc == 1) {
    cb.func_audit = audit_callback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);
    cb.func_log = selinux_log_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);
    return do_server();
+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) {
@@ -321,14 +325,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);