summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/libsystemd.sym.m41
-rw-r--r--src/libsystemd/sd-bus/bus-bloom.c10
-rw-r--r--src/libsystemd/sd-bus/bus-container.c2
-rw-r--r--src/libsystemd/sd-bus/bus-control.c29
-rw-r--r--src/libsystemd/sd-bus/bus-convenience.c37
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c13
-rw-r--r--src/libsystemd/sd-bus/bus-internal.c30
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h2
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c36
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.h2
-rw-r--r--src/libsystemd/sd-bus/bus-message.c21
-rw-r--r--src/libsystemd/sd-bus/bus-message.h2
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c91
-rw-r--r--src/libsystemd/sd-bus/kdbus.h8
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c28
-rw-r--r--src/libsystemd/sd-bus/test-bus-gvariant.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel-bloom.c25
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-marshal.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-signature.c13
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c18
-rw-r--r--src/libsystemd/sd-device/sd-device.c16
-rw-r--r--src/libsystemd/sd-event/sd-event.c7
-rw-r--r--src/libsystemd/sd-hwdb/sd-hwdb.c2
-rw-r--r--src/libsystemd/sd-network/sd-network.c71
-rw-r--r--src/libsystemd/sd-rtnl/rtnl-message.c2
26 files changed, 268 insertions, 204 deletions
diff --git a/src/libsystemd/libsystemd.sym.m4 b/src/libsystemd/libsystemd.sym.m4
index 0b94a87dd6..3121e71282 100644
--- a/src/libsystemd/libsystemd.sym.m4
+++ b/src/libsystemd/libsystemd.sym.m4
@@ -320,6 +320,7 @@ global:
sd_bus_get_name_creds;
sd_bus_get_name_machine_id;
sd_bus_call_method;
+ sd_bus_call_method_async;
sd_bus_get_property;
sd_bus_get_property_trivial;
sd_bus_get_property_string;
diff --git a/src/libsystemd/sd-bus/bus-bloom.c b/src/libsystemd/sd-bus/bus-bloom.c
index 3556774074..91fab90cb0 100644
--- a/src/libsystemd/sd-bus/bus-bloom.c
+++ b/src/libsystemd/sd-bus/bus-bloom.c
@@ -116,11 +116,19 @@ void bloom_add_prefixes(uint64_t filter[], size_t size, unsigned k, const char *
p = stpcpy(stpcpy(c, a), ":");
strcpy(p, b);
+ bloom_add_data(filter, size, k, c, n);
+
for (;;) {
char *e;
e = strrchr(p, sep);
- if (!e || e == p)
+ if (!e)
+ break;
+
+ *(e + 1) = 0;
+ bloom_add_data(filter, size, k, c, e - c + 1);
+
+ if (e == p)
break;
*e = 0;
diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c
index f157c25bba..fa7a207448 100644
--- a/src/libsystemd/sd-bus/bus-container.c
+++ b/src/libsystemd/sd-bus/bus-container.c
@@ -222,7 +222,7 @@ int bus_container_connect_kernel(sd_bus *b) {
if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
return -errno;
- for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
+ CMSG_FOREACH(cmsg, &mh)
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
int *fds;
unsigned n_fds;
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 43ddfc651d..7a59702cb2 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;
@@ -1289,10 +1291,8 @@ int bus_add_match_internal_kernel(
break;
case BUS_MATCH_PATH_NAMESPACE:
- if (!streq(c->value_str, "/")) {
- bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
- using_bloom = true;
- }
+ bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
+ using_bloom = true;
break;
case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
@@ -1308,11 +1308,18 @@ int bus_add_match_internal_kernel(
}
case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
- char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
-
- xsprintf(buf, "arg%i-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
- bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
- using_bloom = true;
+ /*
+ * XXX: DBus spec defines arg[0..63]path= matching to be
+ * a two-way glob. That is, if either string is a prefix
+ * of the other, it matches.
+ * This is really hard to realize in bloom-filters, as
+ * we would have to create a bloom-match for each prefix
+ * of @c->value_str. This is excessive, hence we just
+ * ignore all those matches and accept everything from
+ * the kernel. People should really avoid those matches.
+ * If they're used in real-life some day, we will have
+ * to properly support multiple-matches here.
+ */
break;
}
diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index 28bc8d2818..dfd82e746d 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -58,6 +58,43 @@ _public_ int sd_bus_emit_signal(
return sd_bus_send(bus, m, NULL);
}
+_public_ int sd_bus_call_method_async(
+ sd_bus *bus,
+ sd_bus_slot **slot,
+ const char *destination,
+ const char *path,
+ const char *interface,
+ const char *member,
+ sd_bus_message_handler_t callback,
+ void *userdata,
+ const char *types, ...) {
+
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ int r;
+
+ assert_return(bus, -EINVAL);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
+ r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member);
+ if (r < 0)
+ return r;
+
+ if (!isempty(types)) {
+ va_list ap;
+
+ va_start(ap, types);
+ r = bus_message_append_ap(m, types, ap);
+ va_end(ap);
+ if (r < 0)
+ return r;
+ }
+
+ return sd_bus_call_async(bus, slot, m, callback, userdata, 0);
+}
+
_public_ int sd_bus_call_method(
sd_bus *bus,
const char *destination,
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.c b/src/libsystemd/sd-bus/bus-internal.c
index 91b288cd25..37793e48ed 100644
--- a/src/libsystemd/sd-bus/bus-internal.c
+++ b/src/libsystemd/sd-bus/bus-internal.c
@@ -211,6 +211,17 @@ bool member_name_is_valid(const char *p) {
return true;
}
+/*
+ * Complex pattern match
+ * This checks whether @a is a 'complex-prefix' of @b, or @b is a
+ * 'complex-prefix' of @a, based on strings that consist of labels with @c as
+ * spearator. This function returns true if:
+ * - both strings are equal
+ * - either is a prefix of the other and ends with @c
+ * The second rule makes sure that either string needs to be fully included in
+ * the other, and the string which is considered the prefix needs to end with a
+ * separator.
+ */
static bool complex_pattern_check(char c, const char *a, const char *b) {
bool separator = false;
@@ -222,9 +233,7 @@ static bool complex_pattern_check(char c, const char *a, const char *b) {
for (;;) {
if (*a != *b)
- return (separator && (*a == 0 || *b == 0)) ||
- (*a == 0 && *b == c && b[1] == 0) ||
- (*b == 0 && *a == c && a[1] == 0);
+ return (separator && (*a == 0 || *b == 0));
if (*a == 0)
return true;
@@ -243,7 +252,18 @@ bool path_complex_pattern(const char *pattern, const char *value) {
return complex_pattern_check('/', pattern, value);
}
+/*
+ * Simple pattern match
+ * This checks whether @a is a 'simple-prefix' of @b, based on strings that
+ * consist of labels with @c as separator. This function returns true, if:
+ * - if @a and @b are equal
+ * - if @a is a prefix of @b, and the first following character in @b (or the
+ * last character in @a) is @c
+ * The second rule basically makes sure that if @a is a prefix of @b, then @b
+ * must follow with a new label separated by @c. It cannot extend the label.
+ */
static bool simple_pattern_check(char c, const char *a, const char *b) {
+ bool separator = false;
if (!a && !b)
return true;
@@ -253,11 +273,13 @@ static bool simple_pattern_check(char c, const char *a, const char *b) {
for (;;) {
if (*a != *b)
- return *a == 0 && *b == c;
+ return *a == 0 && (*b == c || separator);
if (*a == 0)
return true;
+ separator = *a == c;
+
a++, b++;
}
}
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-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index d5cc8100ce..3aaaabf4ed 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -498,7 +498,6 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
footer, footer_size,
n_bytes,
fds, n_fds,
- NULL,
seclabel, 0, &m);
if (r < 0)
return r;
@@ -1574,7 +1573,6 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) {
make = alloca0_align(offsetof(struct kdbus_cmd, items) +
ALIGN8(offsetof(struct kdbus_item, bloom_parameter) + sizeof(struct kdbus_bloom_parameter)) +
ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
- ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1),
8);
@@ -1593,14 +1591,6 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) {
make->size += ALIGN8(n->size);
- /* The buses we create make no restrictions on what metadata
- * peers can read from incoming messages. */
- n = KDBUS_ITEM_NEXT(n);
- n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
- n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
- n->data64[0] = _KDBUS_ATTACH_ANY;
- make->size += ALIGN8(n->size);
-
/* Provide all metadata via bus-owner queries */
n = KDBUS_ITEM_NEXT(n);
n->type = KDBUS_ITEM_ATTACH_FLAGS_SEND;
@@ -1770,32 +1760,6 @@ int bus_kernel_realize_attach_flags(sd_bus *bus) {
return 0;
}
-int bus_kernel_fix_attach_mask(void) {
- _cleanup_free_ char *mask = NULL;
- uint64_t m = (uint64_t) -1;
- char buf[2+16+2];
- int r;
-
- /* By default we don't want any kdbus metadata fields to be
- * suppressed, hence we reset the kernel mask for it to
- * (uint64_t) -1. If the module argument was overwritten by
- * the kernel cmdline, we leave it as is. */
-
- r = get_proc_cmdline_key("kdbus.attach_flags_mask=", &mask);
- if (r < 0)
- return log_warning_errno(r, "Failed to read kernel command line: %m");
-
- if (r == 0) {
- sprintf(buf, "0x%" PRIx64 "\n", m);
- r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf);
- if (r < 0)
- return log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to write kdbus attach mask: %m");
- }
-
- return 0;
-}
-
int bus_kernel_get_bus_name(sd_bus *bus, char **name) {
struct kdbus_cmd_info cmd = {
.size = sizeof(struct kdbus_cmd_info),
diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h
index b9f31ba790..bb4dff6d82 100644
--- a/src/libsystemd/sd-bus/bus-kernel.h
+++ b/src/libsystemd/sd-bus/bus-kernel.h
@@ -90,8 +90,6 @@ int bus_kernel_drop_one(int fd);
int bus_kernel_realize_attach_flags(sd_bus *bus);
-int bus_kernel_fix_attach_mask(void);
-
int bus_kernel_get_bus_name(sd_bus *bus, char **name);
int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset);
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 6ee209dd1b..c38b2a5fa5 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -435,7 +435,6 @@ int bus_message_from_header(
size_t message_size,
int *fds,
unsigned n_fds,
- const struct ucred *ucred,
const char *label,
size_t extra,
sd_bus_message **ret) {
@@ -528,23 +527,6 @@ int bus_message_from_header(
m->fds = fds;
m->n_fds = n_fds;
- if (ucred) {
- m->creds.pid = ucred->pid;
- m->creds.euid = ucred->uid;
- m->creds.egid = ucred->gid;
-
- /* Due to namespace translations some data might be
- * missing from this ucred record. */
- if (m->creds.pid > 0)
- m->creds.mask |= SD_BUS_CREDS_PID;
-
- if (m->creds.euid != UID_INVALID)
- m->creds.mask |= SD_BUS_CREDS_EUID;
-
- if (m->creds.egid != GID_INVALID)
- m->creds.mask |= SD_BUS_CREDS_EGID;
- }
-
if (label) {
m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
memcpy(m->creds.label, label, label_sz + 1);
@@ -565,7 +547,6 @@ int bus_message_from_malloc(
size_t length,
int *fds,
unsigned n_fds,
- const struct ucred *ucred,
const char *label,
sd_bus_message **ret) {
@@ -579,7 +560,7 @@ int bus_message_from_malloc(
buffer, length,
length,
fds, n_fds,
- ucred, label,
+ label,
0, &m);
if (r < 0)
return r;
diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
index d784e603dd..088d5b1109 100644
--- a/src/libsystemd/sd-bus/bus-message.h
+++ b/src/libsystemd/sd-bus/bus-message.h
@@ -205,7 +205,6 @@ int bus_message_from_header(
size_t message_size,
int *fds,
unsigned n_fds,
- const struct ucred *ucred,
const char *label,
size_t extra,
sd_bus_message **ret);
@@ -216,7 +215,6 @@ int bus_message_from_malloc(
size_t length,
int *fds,
unsigned n_fds,
- const struct ucred *ucred,
const char *label,
sd_bus_message **ret);
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 4fffc6581d..322d57ddbb 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -500,11 +500,8 @@ 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;
assert(b);
@@ -555,7 +552,9 @@ 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)) {
+ struct cmsghdr *cmsg;
+
+ CMSG_FOREACH(cmsg, &mh)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
int j;
@@ -566,30 +565,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);
@@ -600,18 +578,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 +590,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) {
@@ -738,7 +713,8 @@ int bus_socket_exec(sd_bus *b) {
if (pid == 0) {
/* Child */
- reset_all_signal_handlers();
+ (void) reset_all_signal_handlers();
+ (void) reset_signal_mask();
close_all_fds(s+1, 1);
@@ -914,7 +890,6 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) {
bus->rbuffer, size,
bus->fds, bus->n_fds,
NULL,
- NULL,
&t);
if (r < 0) {
free(b);
@@ -941,11 +916,8 @@ 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;
assert(bus);
@@ -991,7 +963,9 @@ 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)) {
+ struct cmsghdr *cmsg;
+
+ CMSG_FOREACH(cmsg, &mh)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
int n, *f;
@@ -1016,28 +990,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);
diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h
index fc1d77dd7c..00a6e142c9 100644
--- a/src/libsystemd/sd-bus/kdbus.h
+++ b/src/libsystemd/sd-bus/kdbus.h
@@ -5,8 +5,8 @@
* your option) any later version.
*/
-#ifndef _KDBUS_UAPI_H_
-#define _KDBUS_UAPI_H_
+#ifndef _UAPI_KDBUS_H_
+#define _UAPI_KDBUS_H_
#include <linux/ioctl.h>
#include <linux/types.h>
@@ -544,7 +544,7 @@ struct kdbus_msg_info {
* reply to this message. The
* KDBUS_CMD_SEND ioctl() will block
* until the reply is received, and
- * offset_reply in struct kdbus_msg will
+ * reply in struct kdbus_cmd_send will
* yield the offset in the sender's pool
* where the reply can be found.
* This flag is only valid if
@@ -976,4 +976,4 @@ enum kdbus_ioctl_type {
struct kdbus_cmd_match),
};
-#endif /* _KDBUS_UAPI_H_ */
+#endif /* _UAPI_KDBUS_H_ */
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index edc27aef87..2805b29839 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -49,6 +49,21 @@
#include "bus-track.h"
#include "bus-slot.h"
+#define log_debug_bus_message(m) \
+ do { \
+ sd_bus_message *_mm = (m); \
+ log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s", \
+ bus_message_type_to_string(_mm->header->type), \
+ strna(sd_bus_message_get_sender(_mm)), \
+ strna(sd_bus_message_get_destination(_mm)), \
+ strna(sd_bus_message_get_path(_mm)), \
+ strna(sd_bus_message_get_interface(_mm)), \
+ strna(sd_bus_message_get_member(_mm)), \
+ BUS_MESSAGE_COOKIE(_mm), \
+ _mm->reply_cookie, \
+ strna(_mm->error.message)); \
+ } while (false)
+
static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
static int attach_io_events(sd_bus *b);
static void detach_io_events(sd_bus *b);
@@ -116,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);
@@ -1992,6 +2008,7 @@ _public_ int sd_bus_call(
memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
bus->rqueue_size--;
+ log_debug_bus_message(incoming);
if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
@@ -2480,16 +2497,7 @@ static int process_message(sd_bus *bus, sd_bus_message *m) {
bus->current_message = m;
bus->iteration_counter++;
- log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
- bus_message_type_to_string(m->header->type),
- strna(sd_bus_message_get_sender(m)),
- strna(sd_bus_message_get_destination(m)),
- strna(sd_bus_message_get_path(m)),
- strna(sd_bus_message_get_interface(m)),
- strna(sd_bus_message_get_member(m)),
- BUS_MESSAGE_COOKIE(m),
- m->reply_cookie,
- strna(m->error.message));
+ log_debug_bus_message(m);
r = process_hello(bus, m);
if (r != 0)
diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c
index 992edacb28..22ea00c2fb 100644
--- a/src/libsystemd/sd-bus/test-bus-gvariant.c
+++ b/src/libsystemd/sd-bus/test-bus-gvariant.c
@@ -198,7 +198,7 @@ static void test_marshal(void) {
}
#endif
- assert_se(bus_message_from_malloc(bus, blob, sz, NULL, 0, NULL, NULL, &n) >= 0);
+ assert_se(bus_message_from_malloc(bus, blob, sz, NULL, 0, NULL, &n) >= 0);
blob = NULL;
assert_se(bus_message_dump(n, NULL, BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
index b11c43bd7b..90eb1f2a33 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
@@ -26,6 +26,14 @@
#include "bus-kernel.h"
#include "bus-util.h"
+static int test_match(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+ int *found = userdata;
+
+ *found = 1;
+
+ return 0;
+}
+
static void test_one(
const char *path,
const char *interface,
@@ -39,7 +47,7 @@ static void test_one(
_cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL;
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
sd_bus *a, *b;
- int r;
+ int r, found = 0;
assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
@@ -71,7 +79,7 @@ static void test_one(
assert_se(r >= 0);
log_debug("match");
- r = sd_bus_add_match(b, NULL, match, NULL, NULL);
+ r = sd_bus_add_match(b, NULL, match, test_match, &found);
assert_se(r >= 0);
log_debug("signal");
@@ -83,7 +91,7 @@ static void test_one(
assert_se(r >= 0);
r = sd_bus_process(b, &m);
- assert_se(r >= 0 && (good == !!m));
+ assert_se(r >= 0 && good == !!found);
sd_bus_unref(a);
sd_bus_unref(b);
@@ -115,6 +123,17 @@ int main(int argc, char *argv[]) {
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/quux'", false);
+ test_one("/", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true);
+
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar/waldo/'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/'", true);
+
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo/bar/waldo", "arg0path='/foo/'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo", "arg0path='/foo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo", "arg0path='/foo/bar/waldo'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo/", "arg0path='/foo/bar/waldo'", true);
return 0;
}
diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c
index 8f4f60b65f..6506eaab2e 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel.c
@@ -43,8 +43,6 @@ int main(int argc, char *argv[]) {
assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
- bus_kernel_fix_attach_mask();
-
bus_ref = bus_kernel_create_bus(name, false, &bus_name);
if (bus_ref == -ENOENT)
return EXIT_TEST_SKIP;
diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c
index f8ecadf499..a866a56179 100644
--- a/src/libsystemd/sd-bus/test-bus-marshal.c
+++ b/src/libsystemd/sd-bus/test-bus-marshal.c
@@ -212,7 +212,7 @@ int main(int argc, char *argv[]) {
m = sd_bus_message_unref(m);
- r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, NULL, &m);
+ r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m);
assert_se(r >= 0);
bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c
index 4165c9273a..17c6188ca0 100644
--- a/src/libsystemd/sd-bus/test-bus-signature.c
+++ b/src/libsystemd/sd-bus/test-bus-signature.c
@@ -95,23 +95,28 @@ int main(int argc, char *argv[]) {
assert_se(!namespace_complex_pattern("foo.", ""));
assert_se(path_complex_pattern("", ""));
- assert_se(path_complex_pattern("", "/"));
- assert_se(path_complex_pattern("/", ""));
+ assert_se(!path_complex_pattern("", "/"));
+ assert_se(!path_complex_pattern("/", ""));
assert_se(path_complex_pattern("/", "/"));
assert_se(path_complex_pattern("/foobar/", "/"));
- assert_se(path_complex_pattern("/foobar/", "/foobar"));
+ assert_se(!path_complex_pattern("/foobar/", "/foobar"));
assert_se(path_complex_pattern("/foobar", "/foobar"));
- assert_se(path_complex_pattern("/foobar", "/foobar/"));
+ assert_se(!path_complex_pattern("/foobar", "/foobar/"));
assert_se(!path_complex_pattern("/foobar", "/foobar/waldo"));
assert_se(path_complex_pattern("/foobar/", "/foobar/waldo"));
+ assert_se(path_complex_pattern("/foobar/waldo", "/foobar/"));
+
+ assert_se(path_simple_pattern("/foo/", "/foo/bar/waldo"));
assert_se(namespace_simple_pattern("", ""));
+ assert_se(namespace_simple_pattern("", ".foobar"));
assert_se(namespace_simple_pattern("foobar", "foobar"));
assert_se(namespace_simple_pattern("foobar.waldo", "foobar.waldo"));
assert_se(namespace_simple_pattern("foobar", "foobar.waldo"));
assert_se(!namespace_simple_pattern("foobar.waldo", "foobar"));
assert_se(!namespace_simple_pattern("", "foo"));
assert_se(!namespace_simple_pattern("foo", ""));
+ assert_se(namespace_simple_pattern("foo.", "foo.bar.waldo"));
assert_se(streq(object_path_startswith("/foo/bar", "/foo"), "bar"));
assert_se(streq(object_path_startswith("/foo", "/foo"), ""));
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index 3692d46e06..7fd77e9480 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -137,7 +137,6 @@ _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumer
assert_return(enumerator, -EINVAL);
assert_return(_sysattr, -EINVAL);
- assert_return(_value, -EINVAL);
if (match)
hashmap = &enumerator->match_sysattr;
@@ -152,9 +151,11 @@ _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumer
if (!sysattr)
return -ENOMEM;
- value = strdup(_value);
- if (!value)
- return -ENOMEM;
+ if (_value) {
+ value = strdup(_value);
+ if (!value)
+ return -ENOMEM;
+ }
r = hashmap_put(*hashmap, sysattr, value);
if (r < 0)
@@ -174,7 +175,6 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume
assert_return(enumerator, -EINVAL);
assert_return(_property, -EINVAL);
- assert_return(_value, -EINVAL);
r = hashmap_ensure_allocated(&enumerator->match_property, NULL);
if (r < 0)
@@ -184,9 +184,11 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume
if (!property)
return -ENOMEM;
- value = strdup(_value);
- if (!value)
- return -ENOMEM;
+ if (_value) {
+ value = strdup(_value);
+ if (!value)
+ return -ENOMEM;
+ }
r = hashmap_put(enumerator->match_property, property, value);
if (r < 0)
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 97da4a8eea..8e63b9ef56 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -785,7 +785,7 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
path_startswith(device->devpath, "/class/") ||
path_startswith(device->devpath, "/bus/"))
r = device_set_subsystem(device, "subsystem");
- if (r < 0)
+ if (r < 0 && r != -ENOENT)
return log_debug_errno(r, "sd-device: could not set subsystem for %s: %m", device->devpath);
device->subsystem_set = true;
@@ -901,8 +901,11 @@ _public_ int sd_device_get_driver(sd_device *device, const char **ret) {
if (r >= 0) {
r = device_set_driver(device, driver);
if (r < 0)
- return r;
- }
+ return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath);
+ } else if (r == -ENOENT)
+ device->driver_set = true;
+ else
+ return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath);
}
*ret = device->driver;
@@ -1188,6 +1191,8 @@ int device_get_id_filename(sd_device *device, const char **ret) {
return r;
if (major(devnum) > 0) {
+ assert(subsystem);
+
/* use dev_t -- b259:131072, c254:0 */
r = asprintf(&id, "%c%u:%u",
streq(subsystem, "block") ? 'b' : 'c',
@@ -1209,6 +1214,9 @@ int device_get_id_filename(sd_device *device, const char **ret) {
if (!sysname)
return -EINVAL;
+ if (!subsystem)
+ return -EINVAL;
+
r = asprintf(&id, "+%s:%s", subsystem, sysname);
if (r < 0)
return -ENOMEM;
@@ -1262,7 +1270,7 @@ int device_read_db_aux(sd_device *device, bool force) {
}
/* devices with a database entry are initialized */
- device->is_initialized = true;;
+ device->is_initialized = true;
for (i = 0; i < db_len; i++) {
switch (state) {
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index cc8bc50c04..00880c983b 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -474,6 +474,9 @@ static int source_io_unregister(sd_event_source *s) {
assert(s);
assert(s->type == SOURCE_IO);
+ if (event_pid_changed(s->event))
+ return 0;
+
if (!s->io.registered)
return 0;
@@ -604,6 +607,9 @@ static int event_update_signal_fd(sd_event *e) {
assert(e);
+ if (event_pid_changed(e))
+ return 0;
+
add_to_epoll = e->signal_fd < 0;
r = signalfd(e->signal_fd, &e->sigset, SFD_NONBLOCK|SFD_CLOEXEC);
@@ -2378,7 +2384,6 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
}
r = -errno;
-
goto finish;
}
diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c
index 3bbf02896b..2a0e00f7d2 100644
--- a/src/libsystemd/sd-hwdb/sd-hwdb.c
+++ b/src/libsystemd/sd-hwdb/sd-hwdb.c
@@ -317,7 +317,7 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) {
if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 ||
(size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) {
log_debug("error recognizing the format of %s", hwdb_bin_path);
- return -EINVAL;;
+ return -EINVAL;
}
log_debug("=== trie on-disk ===");
diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c
index db1f6997cb..207eda163b 100644
--- a/src/libsystemd/sd-network/sd-network.c
+++ b/src/libsystemd/sd-network/sd-network.c
@@ -297,8 +297,31 @@ static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
return (sd_network_monitor*) (unsigned long) (fd + 1);
}
+static int monitor_add_inotify_watch(int fd) {
+ int k;
+
+ k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
+ if (k >= 0)
+ return 0;
+ else if (errno != ENOENT)
+ return -errno;
+
+ k = inotify_add_watch(fd, "/run/systemd/netif/", IN_CREATE|IN_ISDIR);
+ if (k >= 0)
+ return 0;
+ else if (errno != ENOENT)
+ return -errno;
+
+ k = inotify_add_watch(fd, "/run/systemd/", IN_CREATE|IN_ISDIR);
+ if (k < 0)
+ return -errno;
+
+ return 0;
+}
+
_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
- int fd, k;
+ _cleanup_close_ int fd = -1;
+ int k;
bool good = false;
assert_return(m, -EINVAL);
@@ -308,11 +331,9 @@ _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category
return -errno;
if (!category || streq(category, "links")) {
- k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
- if (k < 0) {
- safe_close(fd);
- return -errno;
- }
+ k = monitor_add_inotify_watch(fd);
+ if (k < 0)
+ return k;
good = true;
}
@@ -323,25 +344,53 @@ _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category
}
*m = FD_TO_MONITOR(fd);
+ fd = -1;
+
return 0;
}
_public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
int fd;
- assert_return(m, NULL);
-
- fd = MONITOR_TO_FD(m);
- close_nointr(fd);
+ if (m) {
+ fd = MONITOR_TO_FD(m);
+ close_nointr(fd);
+ }
return NULL;
}
_public_ int sd_network_monitor_flush(sd_network_monitor *m) {
+ union inotify_event_buffer buffer;
+ struct inotify_event *e;
+ ssize_t l;
+ int fd, k;
assert_return(m, -EINVAL);
- return flush_fd(MONITOR_TO_FD(m));
+ fd = MONITOR_TO_FD(m);
+
+ l = read(fd, &buffer, sizeof(buffer));
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
+
+ return -errno;
+ }
+
+ FOREACH_INOTIFY_EVENT(e, buffer, l) {
+ if (e->mask & IN_ISDIR) {
+ k = monitor_add_inotify_watch(fd);
+ if (k < 0)
+ return k;
+
+ k = inotify_rm_watch(fd, e->wd);
+ if (k < 0)
+ return -errno;
+ }
+ }
+
+ return 0;
}
_public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index bab2a4ff08..9dcf7df559 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1442,7 +1442,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
}
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ CMSG_FOREACH(cmsg, &msg) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {