1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

Merge pull request #85 from keszybz/selinux-context

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2015-06-10 10:20:50 -04:00
commit b078b5a7ab
7 changed files with 40 additions and 103 deletions

View File

@ -261,7 +261,7 @@ int mac_selinux_generic_access_check(
audit_info.path = path;
audit_info.cmdline = cl;
r = selinux_check_access((security_context_t) scon, fcon, tclass, permission, &audit_info);
r = selinux_check_access(scon, fcon, tclass, permission, &audit_info);
if (r < 0)
r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access.");

View File

@ -59,10 +59,7 @@ struct StdoutStream {
int fd;
struct ucred ucred;
#ifdef HAVE_SELINUX
security_context_t security_context;
#endif
char *label;
char *identifier;
char *unit_id;
int priority;
@ -99,12 +96,7 @@ void stdout_stream_free(StdoutStream *s) {
}
safe_close(s->fd);
#ifdef HAVE_SELINUX
if (s->security_context)
freecon(s->security_context);
#endif
free(s->label);
free(s->identifier);
free(s->unit_id);
free(s->state_file);
@ -225,8 +217,7 @@ static int stdout_stream_log(StdoutStream *s, const char *p) {
char syslog_facility[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1];
_cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
unsigned n = 0;
char *label = NULL;
size_t label_len = 0;
size_t label_len;
assert(s);
assert(p);
@ -271,14 +262,8 @@ static int stdout_stream_log(StdoutStream *s, const char *p) {
if (message)
IOVEC_SET_STRING(iovec[n++], message);
#ifdef HAVE_SELINUX
if (s->security_context) {
label = (char*) s->security_context;
label_len = strlen((char*) s->security_context);
}
#endif
server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority, 0);
label_len = s->label ? strlen(s->label) : 0;
server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, s->label, label_len, s->unit_id, priority, 0);
return 0;
}
@ -489,12 +474,11 @@ static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
if (r < 0)
return log_error_errno(r, "Failed to determine peer credentials: %m");
#ifdef HAVE_SELINUX
if (mac_selinux_use()) {
if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT)
log_error_errno(errno, "Failed to determine peer security context: %m");
r = getpeersec(fd, &stream->label);
if (r < 0 && r != -EOPNOTSUPP)
(void) log_warning_errno(r, "Failed to determine peer security context: %m");
}
#endif
(void) shutdown(fd, SHUT_WR);

View File

@ -979,8 +979,10 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **
_cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
pid_t pid = 0;
int r;
bool do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT);
if (!bus->ucred_valid && isempty(bus->label))
/* Avoid allocating anything if we have no chance of returning useful data */
if (!bus->ucred_valid && !do_label)
return -ENODATA;
c = bus_creds_new();
@ -1004,7 +1006,7 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **
}
}
if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
if (do_label) {
c->label = strdup(bus->label);
if (!c->label)
return -ENOMEM;

View File

@ -773,11 +773,13 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
return 0;
/* Try to retrieve PID from creds if it wasn't passed to us */
if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
if (pid > 0) {
c->pid = pid;
c->mask |= SD_BUS_CREDS_PID;
} else if (c->mask & SD_BUS_CREDS_PID)
pid = c->pid;
/* Without pid we cannot do much... */
if (pid <= 0)
else
/* Without pid we cannot do much... */
return 0;
/* Try to retrieve TID from creds if it wasn't passed to us */
@ -789,9 +791,6 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
if (missing == 0)
return 0;
c->pid = pid;
c->mask |= SD_BUS_CREDS_PID;
if (tid > 0) {
c->tid = tid;
c->mask |= SD_BUS_CREDS_TID;

View File

@ -261,7 +261,7 @@ struct sd_bus {
usec_t auth_timeout;
struct ucred ucred;
char label[NAME_MAX];
char *label;
uint64_t creds_mask;

View File

@ -500,9 +500,7 @@ static int bus_socket_read_auth(sd_bus *b) {
void *p;
union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(NAME_MAX)]; /*selinux label */
uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
} control;
struct cmsghdr *cmsg;
bool handle_cmsg = false;
@ -554,8 +552,8 @@ static int bus_socket_read_auth(sd_bus *b) {
b->rbuffer_size += k;
if (handle_cmsg) {
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
if (handle_cmsg)
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
int j;
@ -566,31 +564,9 @@ static int bus_socket_read_auth(sd_bus *b) {
j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
close_many((int*) CMSG_DATA(cmsg), j);
return -EIO;
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
/* Ignore bogus data, which we might
* get on socketpair() sockets */
if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
b->ucred_valid = true;
}
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_SECURITY) {
size_t l;
l = cmsg->cmsg_len - CMSG_LEN(0);
if (l > 0) {
memcpy(&b->label, CMSG_DATA(cmsg), l);
b->label[l] = 0;
}
}
}
}
} else
log_debug("Got unexpected auxiliary data with level=%d and type=%d",
cmsg->cmsg_level, cmsg->cmsg_type);
r = bus_socket_auth_verify(b);
if (r != 0)
@ -600,18 +576,8 @@ static int bus_socket_read_auth(sd_bus *b) {
}
void bus_socket_setup(sd_bus *b) {
int enable;
assert(b);
/* Enable SO_PASSCRED + SO_PASSEC. We try this on any
* socket, just in case. */
enable = !b->bus_client;
(void) setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
enable = !b->bus_client && (b->attach_flags & KDBUS_ATTACH_SECLABEL);
(void) setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
/* Increase the buffers to 8 MB */
fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
@ -622,10 +588,17 @@ void bus_socket_setup(sd_bus *b) {
}
static void bus_get_peercred(sd_bus *b) {
int r;
assert(b);
/* Get the peer for socketpair() sockets */
b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
/* Get the SELinux context of the peer */
r = getpeersec(b->input_fd, &b->label);
if (r < 0 && r != -EOPNOTSUPP)
log_debug_errno(r, "Failed to determine peer security context: %m");
}
static int bus_socket_start_auth_client(sd_bus *b) {
@ -941,9 +914,7 @@ int bus_socket_read_message(sd_bus *bus) {
void *b;
union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(NAME_MAX)]; /*selinux label */
uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
} control;
struct cmsghdr *cmsg;
bool handle_cmsg = false;
@ -990,8 +961,8 @@ int bus_socket_read_message(sd_bus *bus) {
bus->rbuffer_size += k;
if (handle_cmsg) {
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
if (handle_cmsg)
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
int n, *f;
@ -1016,29 +987,9 @@ int bus_socket_read_message(sd_bus *bus) {
memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
bus->fds = f;
bus->n_fds += n;
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
/* Ignore bogus data, which we might
* get on socketpair() sockets */
if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
bus->ucred_valid = true;
}
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_SECURITY) {
size_t l;
l = cmsg->cmsg_len - CMSG_LEN(0);
if (l > 0) {
memcpy(&bus->label, CMSG_DATA(cmsg), l);
bus->label[l] = 0;
}
}
}
}
} else
log_debug("Got unexpected auxiliary data with level=%d and type=%d",
cmsg->cmsg_level, cmsg->cmsg_type);
r = bus_socket_read_message_need(bus, &need);
if (r < 0)

View File

@ -131,6 +131,7 @@ static void bus_free(sd_bus *b) {
if (b->kdbus_buffer)
munmap(b->kdbus_buffer, KDBUS_POOL_SIZE);
free(b->label);
free(b->rbuffer);
free(b->unique_name);
free(b->auth_buffer);