summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus')
-rw-r--r--src/libsystemd/sd-bus/bus-control.c6
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c13
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h2
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c87
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c1
5 files changed, 31 insertions, 78 deletions
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index b4ca177f76..1103903358 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -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;
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 4d67619cf8..1c365b7fcd 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -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;
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 1351938c80..2ee0eabc02 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -261,7 +261,7 @@ struct sd_bus {
usec_t auth_timeout;
struct ucred ucred;
- char label[NAME_MAX];
+ char *label;
uint64_t creds_mask;
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 5209db8c4d..9f3756f0c2 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -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)
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 598b1be8a6..2805b29839 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -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);