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:
commit
b078b5a7ab
@ -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.");
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -261,7 +261,7 @@ struct sd_bus {
|
||||
usec_t auth_timeout;
|
||||
|
||||
struct ucred ucred;
|
||||
char label[NAME_MAX];
|
||||
char *label;
|
||||
|
||||
uint64_t creds_mask;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user