selinux: fix various problems

This commit is contained in:
Daniel J Walsh 2012-09-28 10:26:59 -04:00 committed by Lennart Poettering
parent 760c85c0bd
commit d67227c8b9

View file

@ -252,9 +252,22 @@ static int audit_callback(void *auditdata, security_class_t cls,
{ {
struct auditstruct *audit = (struct auditstruct *) auditdata; struct auditstruct *audit = (struct auditstruct *) auditdata;
snprintf(msgbuf, msgbufsize, snprintf(msgbuf, msgbufsize,
"name=\"%s\" cmdline=\"%s\" auid=%d uid=%d gid=%d", "auid=%d uid=%d gid=%d",
audit->path, audit->cmdline, audit->loginuid, audit->loginuid,
audit->uid, audit->gid); audit->uid, audit->gid);
if (audit->path) {
strncat(msgbuf," path=\"", msgbufsize);
strncat(msgbuf, audit->path, msgbufsize);
strncat(msgbuf,"\"", msgbufsize);
}
if (audit->cmdline) {
strncat(msgbuf," cmdline=\"", msgbufsize);
strncat(msgbuf, audit->cmdline, msgbufsize);
strncat(msgbuf,"\"", msgbufsize);
}
return 0; return 0;
} }
@ -295,7 +308,7 @@ static int access_init(void) {
int r = -1; int r = -1;
if (avc_open(NULL, 0)) { if (avc_open(NULL, 0)) {
log_full(LOG_ERR, "avc_open failed: %m\n"); log_error("avc_open failed: %m");
return -errno; return -errno;
} }
@ -329,13 +342,12 @@ static int selinux_init(Manager *m, DBusError *error) {
/* if not first time is not set, then initialize access */ /* if not first time is not set, then initialize access */
r = access_init(); r = access_init();
if (r < 0) { if (r < 0) {
dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Unable to initialize SELinux."); dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to initialize SELinux.");
return r; return r;
} }
first_time = 0;
} }
first_time = 0;
return 0; return 0;
} }
@ -392,6 +404,7 @@ static int get_calling_context(
const char *sender; const char *sender;
int r; int r;
int fd;
/* /*
If sender exists then If sender exists then
@ -401,17 +414,22 @@ static int get_calling_context(
sender = dbus_message_get_sender(message); sender = dbus_message_get_sender(message);
if (sender) { if (sender) {
r = bus_get_selinux_security_context(connection, sender, scon, error); r = bus_get_selinux_security_context(connection, sender, scon, error);
if (r < 0) if (r == 0)
return -EINVAL; return 0;
} else {
int fd;
r = dbus_connection_get_unix_fd(connection, &fd);
if (! r)
return -EINVAL;
r = getpeercon(fd, scon); log_debug("bus_get_selinux_security_context failed %m");
if (r < 0) }
return -errno;
r = dbus_connection_get_unix_fd(connection, &fd);
if (! r) {
log_error("bus_connection_get_unix_fd failed %m");
return -EINVAL;
}
r = getpeercon(fd, scon);
if (r < 0) {
log_error("getpeercon failed %m");
return -errno;
} }
return 0; return 0;
@ -461,15 +479,18 @@ static int selinux_access_check(DBusConnection *connection, DBusMessage *message
audit.path = path; audit.path = path;
r = get_calling_context(connection, message, &scon, error); r = get_calling_context(connection, message, &scon, error);
if (r != 0) if (r != 0) {
log_error("Failed to get caller's security context on: %m");
goto finish; goto finish;
}
if (path) { if (path) {
tclass = "service"; tclass = "service";
/* get the file context of the unit file */ /* get the file context of the unit file */
r = getfilecon(path, &fcon); r = getfilecon(path, &fcon);
if (r < 0) { if (r < 0) {
log_full(LOG_ERR, "Failed to get security context on: %s %m\n",path); dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path);
r = -errno;
log_error("Failed to get security context on: %s %m",path);
goto finish; goto finish;
} }
@ -477,7 +498,9 @@ static int selinux_access_check(DBusConnection *connection, DBusMessage *message
tclass = "system"; tclass = "system";
r = getcon(&fcon); r = getcon(&fcon);
if (r < 0) { if (r < 0) {
dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Unable to get current context, SELinux policy denies access."); dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get current context.");
r = -errno;
log_error("Failed to get current process context on: %m");
goto finish; goto finish;
} }
} }
@ -488,16 +511,12 @@ static int selinux_access_check(DBusConnection *connection, DBusMessage *message
r = selinux_check_access(scon, fcon, tclass, perm, &audit); r = selinux_check_access(scon, fcon, tclass, perm, &audit);
if (r < 0) { if (r < 0) {
r = -errno; r = -errno;
log_error("SELinux Denied \"%s\"", audit.cmdline); log_error("SELinux policy denies access.");
dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "SELinux policy denies access."); dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "SELinux policy denies access.");
} }
log_debug("SELinux checkaccess scon %s tcon %s tclass %s perm %s path %s: %d", scon, fcon, tclass, perm, path, r); log_debug("SELinux checkaccess scon %s tcon %s tclass %s perm %s path %s cmdline %s: %d", scon, fcon, tclass, perm, path, audit.cmdline, r);
finish: finish:
if (r)
r = -errno;
free(audit.cmdline); free(audit.cmdline);
freecon(scon); freecon(scon);
freecon(fcon); freecon(fcon);
@ -520,6 +539,7 @@ int selinux_unit_access_check(DBusConnection *connection, DBusMessage *message,
const char *member; const char *member;
int r; int r;
log_debug("SELinux unit access check %s\n", path);
r = selinux_init(m, error); r = selinux_init(m, error);
if (r < 0) if (r < 0)
return r; return r;
@ -533,7 +553,9 @@ int selinux_unit_access_check(DBusConnection *connection, DBusMessage *message,
log_debug("SELinux dbus-unit Look %s up perm %s require_unit %d", member, perm, require_unit); log_debug("SELinux dbus-unit Look %s up perm %s require_unit %d", member, perm, require_unit);
r = selinux_access_check(connection, message, m, error, perm, path); r = selinux_access_check(connection, message, m, error, perm, path);
if (r < 0 && !selinux_enforcing) {
/* if SELinux is in permissive mode return 0 */
if (r && (security_getenforce() != 1 )) {
dbus_error_init(error); dbus_error_init(error);
r = 0; r = 0;
} }
@ -548,6 +570,7 @@ int selinux_manager_access_check(DBusConnection *connection, DBusMessage *messag
const char *perm; const char *perm;
char *path = NULL; char *path = NULL;
log_debug("SELinux manager access check\n");
r = selinux_init(m, error); r = selinux_init(m, error);
if (r < 0) if (r < 0)
return r; return r;
@ -561,31 +584,64 @@ int selinux_manager_access_check(DBusConnection *connection, DBusMessage *messag
log_debug("SELinux dbus-manager Lookup %s perm %s require_unit %d", member, perm, require_unit); log_debug("SELinux dbus-manager Lookup %s perm %s require_unit %d", member, perm, require_unit);
if (require_unit) { if (require_unit) {
const char *name; const char *name, *smode, *old_name = NULL;
Unit *u; Unit *u;
if (!dbus_message_get_args( if (! dbus_message_get_args(
message, message,
error, error,
DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old_name,
DBUS_TYPE_INVALID)) { DBUS_TYPE_STRING, &name,
r = -EINVAL; DBUS_TYPE_STRING, &smode,
goto finish; DBUS_TYPE_INVALID)) {
dbus_error_init(error);
if (!dbus_message_get_args(
message,
error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &smode,
DBUS_TYPE_INVALID)) {
dbus_error_init(error);
if (!dbus_message_get_args(
message,
error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID)) {
r = -EINVAL;
/* This is broken for now, if I can not get a name
return success.
*/
log_error("SELinux dbus-manager failed to find unit %m");
r = 0;
goto finish;
}
}
} }
log_debug("SELinux dbus-manager load unit %s", name);
r = manager_load_unit(m, name, NULL, error, &u); r = manager_load_unit(m, name, NULL, error, &u);
if (r < 0) { if (r < 0) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); log_error("Unit %s is not loaded.", name);
/* This is broken for now, if I can not load a unit
return success.
*/
dbus_error_init(error);
r = 0;
goto finish; goto finish;
} }
path = u->source_path ? u->source_path : u->fragment_path; path = u->source_path ? u->source_path : u->fragment_path;
if (!path) {
// r = -1;
log_error("Unit %s does not have path.", name);
goto finish;
}
} }
r = selinux_access_check(connection, message, m, error, perm, path); r = selinux_access_check(connection, message, m, error, perm, path);
finish: finish:
/* if SELinux is in permissive mode return 0 */ /* if SELinux is in permissive mode return 0 */
if (r && (!selinux_enforcing)) { if (r && (security_getenforce() != 1 )) {
dbus_error_init(error); dbus_error_init(error);
r = 0; r = 0;
} }