am 2fb90dc8: Merge changes from topic \'userspace-audit\'

* commit '2fb90dc8b2b590e674c5e433e8bf3d3f08a887c8':
  debuggerd: audit pid, uid and gid on SE Linux denial
  property_service: log pid,uid and gid of setprop client
This commit is contained in:
Nick Kralevich 2015-10-10 20:11:08 +00:00 committed by Android Git Automerger
commit 545b7c9e39
4 changed files with 51 additions and 17 deletions

View File

@ -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();

View File

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

View File

@ -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",

View File

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