debuggerd: audit pid, uid and gid on SE Linux denial

When debugging SE Linux audit messages from debuggerd, its
unclear what process is triggering the access violation. To
assist in debugging, we also log pid, uid and gid.

Before:
avc:  denied  { dump_backtrace } for scontext=u:r:dumpstate:s0 ...

After:
avc: denied  { dump_backtrace } for pid=198 uid=1019 gid=1019 ..

Change-Id: I8263e6f5e77917139b73c3e84b76f7f97fd98003
Signed-off-by: William Roberts <william.c.roberts@intel.com>
This commit is contained in:
William Roberts 2015-10-06 12:03:01 -07:00
parent d7aea443d9
commit 468573930d
1 changed files with 23 additions and 8 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();