diff options
author | Łukasz Stelmach <l.stelmach@samsung.com> | 2024-07-29 10:14:57 +0200 |
---|---|---|
committer | Łukasz Stelmach <l.stelmach@samsung.com> | 2024-08-19 15:25:59 +0200 |
commit | 9911ecd64fe169b4a030cc0681565adc5e973ec3 (patch) | |
tree | bfceb3043fa281dbb1bd1701264e0831caa0785e | |
parent | 105d890d8d80e9eec858a1b068b7af7f08963cc0 (diff) | |
download | systemd-sandbox/lstelmach/kdbus-tizen-next.tar.gz systemd-sandbox/lstelmach/kdbus-tizen-next.tar.bz2 systemd-sandbox/lstelmach/kdbus-tizen-next.zip |
WIP: kdbussandbox/lstelmach/kdbus-tizen-next
Change-Id: I17cca7fee7c324250a221f081f1c464625e77246
-rw-r--r-- | src/core/bus-policy.c | 7 | ||||
-rw-r--r-- | src/core/busname.c | 85 | ||||
-rw-r--r-- | src/core/busname.h | 2 | ||||
-rw-r--r-- | src/core/dbus-busname.c | 1 | ||||
-rw-r--r-- | src/core/dbus.c | 9 | ||||
-rw-r--r-- | src/core/load-fragment.c | 2 | ||||
-rw-r--r-- | src/dbus1-generator/dbus1-generator.c | 11 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-bloom.c | 6 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-control-kernel.c | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-internal.h | 5 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 1 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.h | 3 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-message.c | 388 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-message.h | 18 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 22 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-benchmark.c | 1 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-gvariant.c | 1 | ||||
-rw-r--r-- | src/login/pam_systemd.c | 6 | ||||
-rw-r--r-- | src/nspawn/nspawn-mount.c | 4 | ||||
-rw-r--r-- | src/shared/bus-util.c | 6 |
20 files changed, 497 insertions, 85 deletions
diff --git a/src/core/bus-policy.c b/src/core/bus-policy.c index e1590f855d..73d9add3ee 100644 --- a/src/core/bus-policy.c +++ b/src/core/bus-policy.c @@ -24,9 +24,9 @@ #include "alloc-util.h" #include "bus-kernel.h" #include "bus-policy.h" +#include "macro.h" #include "string-table.h" #include "user-util.h" -#include "util.h" int bus_kernel_translate_access(BusPolicyAccess access) { assert(access >= 0); @@ -44,7 +44,7 @@ int bus_kernel_translate_access(BusPolicyAccess access) { return KDBUS_POLICY_OWN; default: - assert_not_reached("Unknown policy access"); + assert_not_reached(); } } @@ -83,7 +83,7 @@ int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item * } default: - assert_not_reached("Unknown policy type"); + assert_not_reached(); } item->policy_access.access = bus_kernel_translate_access(policy->access); @@ -103,7 +103,6 @@ int bus_kernel_make_starter( struct kdbus_cmd_hello *hello; struct kdbus_item *n; size_t policy_cnt = 0; - BusNamePolicy *po; size_t size; int r; diff --git a/src/core/busname.c b/src/core/busname.c index a1523c84e9..31c58ac966 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -30,6 +30,7 @@ #include "dbus-busname.h" #include "fd-util.h" #include "format-util.h" +#include "macro.h" #include "memory-util.h" #include "parse-util.h" #include "process-util.h" @@ -64,17 +65,19 @@ static void busname_init(Unit *u) { n->accept_fd = true; n->activating = true; - n->timeout_usec = u->manager->default_timeout_start_usec; + n->control_pid = PIDREF_NULL; + + n->timeout_usec = u->manager->defaults.timeout_start_usec; } static void busname_unwatch_control_pid(BusName *n) { assert(n); - if (n->control_pid <= 0) + if (!pidref_is_set(&n->control_pid)) return; - unit_unwatch_pid(UNIT(n), n->control_pid); - n->control_pid = 0; + unit_unwatch_pidref(UNIT(n), &n->control_pid); + pidref_done(&n->control_pid); } static void busname_free_policy(BusName *n) { @@ -265,10 +268,10 @@ static void busname_dump(Unit *u, FILE *f, const char *prefix) { prefix, yes_no(n->activating), prefix, yes_no(n->accept_fd)); - if (n->control_pid > 0) + if (pidref_is_set(&n->control_pid)) fprintf(f, "%sControl PID: "PID_FMT"\n", - prefix, n->control_pid); + prefix, n->control_pid.pid); } static void busname_unwatch_fd(BusName *n) { @@ -363,11 +366,11 @@ static int busname_coldplug(Unit *u) { if (n->deserialized_state == n->state) return 0; - if (n->control_pid > 0 && - pid_is_unwaited(n->control_pid) && + if (pidref_is_set(&n->control_pid) && + pidref_is_unwaited(&n->control_pid) > 0 && IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) { - r = unit_watch_pid(UNIT(n), n->control_pid, false); + r = unit_watch_pidref(UNIT(n), &n->control_pid, false); if (r < 0) return r; @@ -392,10 +395,14 @@ static int busname_coldplug(Unit *u) { return 0; } -static int busname_make_starter(BusName *n, pid_t *_pid) { +static int busname_make_starter(BusName *n, PidRef *ret_pid) { + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; pid_t pid; int r; + assert(n); + assert(ret_pid); + r = busname_arm_timer(n, usec_add(now(CLOCK_MONOTONIC), n->timeout_usec)); if (r < 0) goto fail; @@ -430,11 +437,15 @@ static int busname_make_starter(BusName *n, pid_t *_pid) { _exit(ret); } - r = unit_watch_pid(UNIT(n), pid, true); + r = pidref_set_pid(&pidref, pid); + if (r < 0) + return r; + + r = unit_watch_pidref(UNIT(n), &pidref, /* excluseive= */ true); if (r < 0) goto fail; - *_pid = pid; + *ret_pid = TAKE_PIDREF(pidref); return 0; fail: @@ -465,9 +476,9 @@ static void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f r = unit_kill_context(UNIT(n), &kill_context, state != BUSNAME_SIGTERM ? KILL_KILL : KILL_TERMINATE, - -1, - n->control_pid, - false); + /* main_pid= */ NULL, + /* control_pid= */ &n->control_pid, + /* main_pid_alien= */ false); if (r < 0) { log_unit_warning_errno(UNIT(n), r, "Failed to kill control process: %m"); goto fail; @@ -559,9 +570,7 @@ static void busname_enter_running(BusName *n) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; bool pending = false; Unit *other; - Iterator i; int r; - void *v; assert(n); @@ -583,7 +592,7 @@ static void busname_enter_running(BusName *n) { /* If there's already a start pending don't bother to do * anything */ - HASHMAP_FOREACH_KEY(v, other, UNIT(n)->dependencies[UNIT_TRIGGERS], i) + UNIT_FOREACH_DEPENDENCY(other, UNIT(n), UNIT_ATOM_TRIGGERS) if (unit_active_or_pending(other)) { pending = true; break; @@ -686,9 +695,7 @@ static int busname_serialize(Unit *u, FILE *f, FDSet *fds) { (void) serialize_item(f, "state", busname_state_to_string(n->state)); (void) serialize_item(f, "result", busname_result_to_string(n->result)); - - if (n->control_pid > 0) - (void) serialize_item_format(f, "control-pid", PID_FMT, n->control_pid); + (void) serialize_pidref(f, fds, "control-pid", &n->control_pid); r = serialize_fd(f, fds, "starter-fd", n->starter_fd); if (r < 0) @@ -723,12 +730,10 @@ static int busname_deserialize_item(Unit *u, const char *key, const char *value, n->result = f; } else if (streq(key, "control-pid")) { - pid_t pid; - if (parse_pid(value, &pid) < 0) - log_unit_debug(u, "Failed to parse control-pid value: %s", value); - else - n->control_pid = pid; + pidref_done(&n->control_pid); + (void) deserialize_pidref(fds, value, &n->control_pid); + } else if (streq(key, "starter-fd")) { int fd; @@ -871,10 +876,10 @@ static void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) { assert(n); assert(pid >= 0); - if (pid != n->control_pid) + if (pid != n->control_pid.pid) return; - n->control_pid = 0; + pidref_done(&n->control_pid); if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL)) f = BUSNAME_SUCCESS; @@ -885,9 +890,9 @@ static void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) { else if (code == CLD_DUMPED) f = BUSNAME_FAILURE_CORE_DUMP; else - assert_not_reached("Unknown sigchld code"); + assert_not_reached(); - log_unit_full(u, f == BUSNAME_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0, + log_unit_full(u, f == BUSNAME_SUCCESS ? LOG_DEBUG : LOG_NOTICE, "Control process exited, code=%s status=%i", sigchld_code_to_string(code), status); if (n->result == BUSNAME_SUCCESS) @@ -908,7 +913,7 @@ static void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) { break; default: - assert_not_reached("Uh, control process died at wrong time."); + assert_not_reached(); } /* Notify clients about changed exit status */ @@ -939,7 +944,7 @@ static int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *us break; default: - assert_not_reached("Timeout at wrong time."); + assert_not_reached(); } return 0; @@ -983,10 +988,6 @@ static void busname_trigger_notify(Unit *u, Unit *other) { busname_set_state(n, BUSNAME_RUNNING); } -static int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { - return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error); -} - static int busname_get_timeout(Unit *u, usec_t *timeout) { BusName *n = BUSNAME(u); usec_t t; @@ -1009,12 +1010,8 @@ static bool busname_supported(void) { return is_kdbus_available(); } -static int busname_control_pid(Unit *u) { - BusName *n = BUSNAME(u); - - assert(n); - - return n->control_pid; +static PidRef* busname_control_pid(Unit *u) { + return &ASSERT_PTR(BUSNAME(u))->control_pid; } static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = { @@ -1052,8 +1049,6 @@ const UnitVTable busname_vtable = { .start = busname_start, .stop = busname_stop, - .kill = busname_kill, - .get_timeout = busname_get_timeout, .serialize = busname_serialize, @@ -1072,8 +1067,6 @@ const UnitVTable busname_vtable = { .control_pid = busname_control_pid, - .bus_vtable = bus_busname_vtable, - .status_message_formats = { .finished_start_job = { [JOB_DONE] = "Listening on %s.", diff --git a/src/core/busname.h b/src/core/busname.h index 9514078a2d..9ddc18db10 100644 --- a/src/core/busname.h +++ b/src/core/busname.h @@ -57,7 +57,7 @@ struct BusName { sd_event_source *starter_event_source; sd_event_source *timer_event_source; - pid_t control_pid; + PidRef control_pid; LIST_HEAD(BusNamePolicy, policy); BusPolicyAccess policy_world; diff --git a/src/core/dbus-busname.c b/src/core/dbus-busname.c index cf816ba15b..543060e043 100644 --- a/src/core/dbus-busname.c +++ b/src/core/dbus-busname.c @@ -17,6 +17,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "bus-get-properties.h" #include "bus-util.h" #include "busname.h" #include "dbus-busname.h" diff --git a/src/core/dbus.c b/src/core/dbus.c index 02426e980b..9a4b47d5f3 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -13,6 +13,7 @@ #include "bus-polkit.h" #include "bus-util.h" #include "dbus-automount.h" +#include "dbus-busname.h" #include "dbus-cgroup.h" #include "dbus-device.h" #include "dbus-execute.h" @@ -483,6 +484,13 @@ static const BusObjectImplementation bus_automount_object = { { bus_automount_vtable, bus_unit_interface_find }), }; +static const BusObjectImplementation bus_busname_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.BusName", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_busname_vtable, bus_unit_interface_find }), +}; + static const BusObjectImplementation bus_device_object = { "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Device", @@ -582,6 +590,7 @@ static const BusObjectImplementation bus_manager_object = { &job_object, &unit_object, &bus_automount_object, + &bus_busname_object, &bus_device_object, &bus_mount_object, &bus_path_object, diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 7fbfea9e5a..72ac0e21f5 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2729,7 +2729,7 @@ int config_parse_bus_policy( else if (streq(lvalue, "AllowGroup")) p->type = BUSNAME_POLICY_TYPE_GROUP; else - assert_not_reached("Unknown lvalue"); + assert_not_reached(); id_str = strdup(rvalue); if (!id_str) diff --git a/src/dbus1-generator/dbus1-generator.c b/src/dbus1-generator/dbus1-generator.c index ec2ac9b7dc..e4cb8c8be9 100644 --- a/src/dbus1-generator/dbus1-generator.c +++ b/src/dbus1-generator/dbus1-generator.c @@ -29,9 +29,9 @@ #include "fd-util.h" #include "fileio.h" #include "mkdir.h" +#include "mkdir-label.h" #include "special.h" #include "unit-name.h" -#include "util.h" static const char *arg_dest_late = "/tmp", *arg_dest = "/tmp"; @@ -172,7 +172,7 @@ static int add_dbus(const char *path, const char *fname, const char *type) { r = config_parse(NULL, p, NULL, "D-BUS Service\0", config_item_table_lookup, table, - CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN, NULL); + CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN, NULL, NULL); if (r < 0) return r; @@ -217,7 +217,6 @@ static int add_dbus(const char *path, const char *fname, const char *type) { static int parse_dbus_fragments(const char *path, const char *type) { _cleanup_closedir_ DIR *d = NULL; - struct dirent *de; int r; assert(path); @@ -304,7 +303,7 @@ static int create_compatibility(const char *units, const char *type) { "Description=DBUS1: dbus.socket for kdbus compatibility\n" "[Socket]\n" "SmackLabelIPIn=^\n" - "ListenStream=@/tmp/.kdbus_bus_%s_%d\n", type, getuid()); + "ListenStream=@/tmp/.kdbus_bus_%s_"UID_FMT"\n", type, getuid()); r = fflush_and_check(f); @@ -344,11 +343,11 @@ int main(int argc, char *argv[]) { if (r >= 0) { path = "/usr/share/dbus-1/services"; type = "session"; - units = USER_DATA_UNIT_PATH; + units = USER_DATA_UNIT_DIR; } else if (r == -ENXIO) { path = "/usr/share/dbus-1/system-services"; type = "system"; - units = SYSTEM_DATA_UNIT_PATH; + units = SYSTEM_DATA_UNIT_DIR; } else return log_error_errno(r, "Failed to determine whether we are running as user or system instance: %m"); diff --git a/src/libsystemd/sd-bus/bus-bloom.c b/src/libsystemd/sd-bus/bus-bloom.c index 900c14f45b..adcd09f5ad 100644 --- a/src/libsystemd/sd-bus/bus-bloom.c +++ b/src/libsystemd/sd-bus/bus-bloom.c @@ -21,7 +21,7 @@ #include "bus-bloom.h" #include "sd-id128.h" #include "siphash24.h" -#include "util.h" +#include "logarithm.h" static inline void set_bit(uint64_t filter[], unsigned long b) { filter[b >> 6] |= 1ULL << (b & 63); @@ -57,7 +57,7 @@ static void bloom_add_data( m = size * 8; /* Determine how many bytes we need to generate a bit index 0..m for this filter */ - w = (u64log2(m) + 7) / 8; + w = (log2u64(m) + 7) / 8; assert(w <= sizeof(uint64_t)); @@ -147,7 +147,7 @@ bool bloom_validate_parameters(size_t size, unsigned k) { return false; m = size * 8; - w = (u64log2(m) + 7) / 8; + w = (log2u64(m) + 7) / 8; if (w > sizeof(uint64_t)) return false; diff --git a/src/libsystemd/sd-bus/bus-control-kernel.c b/src/libsystemd/sd-bus/bus-control-kernel.c index 09d9638464..8ade1a1902 100644 --- a/src/libsystemd/sd-bus/bus-control-kernel.c +++ b/src/libsystemd/sd-bus/bus-control-kernel.c @@ -33,9 +33,9 @@ #include "bus-control-kernel.h" #include "bus-internal.h" #include "bus-message.h" -#include "bus-util.h" #include "bus-slot.h" #include "capability-util.h" +#include "macro.h" #include "process-util.h" #include "stdio-util.h" #include "string-util.h" @@ -1165,7 +1165,7 @@ int bus_add_match_internal_kernel( case BUS_MATCH_LEAF: case _BUS_MATCH_NODE_TYPE_MAX: case _BUS_MATCH_NODE_TYPE_INVALID: - assert_not_reached("Invalid match type?"); + assert_not_reached(); } } diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 6c78956723..dd9134fc7a 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -10,6 +10,7 @@ #include "bus-kernel.h" #include "bus-match.h" #include "constants.h" +#include "format-util.h" #include "hashmap.h" #include "list.h" #include "prioq.h" @@ -212,6 +213,8 @@ struct sd_bus { bool fake_creds_valid:1; bool fake_pids_valid:1; bool manual_peer_interface:1; + bool is_system:1; + bool is_user:1; bool allow_interactive_authorization:1; bool exit_on_disconnect:1; bool exited:1; @@ -259,6 +262,8 @@ struct sd_bus { pid_t nspid; char *machine; + char *kernel; + sd_id128_t server_id; char *address; diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 2c8bf7decb..b262f13502 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -6,6 +6,7 @@ #include <fcntl.h> #include <malloc.h> +#include <sys/ioctl.h> #include <sys/mman.h> #include <sys/prctl.h> diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h index 8fd951da7d..62b5b2a0e1 100644 --- a/src/libsystemd/sd-bus/bus-kernel.h +++ b/src/libsystemd/sd-bus/bus-kernel.h @@ -43,6 +43,9 @@ struct memfd_cache { size_t allocated; }; +void close_and_munmap(int fd, void *address, size_t size); +void bus_flush_memfd(sd_bus *bus); + int bus_kernel_connect(sd_bus *b); int bus_kernel_take_fd(sd_bus *b); diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index b5e15c214d..1a132efdde 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -432,7 +432,7 @@ static int message_append_reply_cookie(sd_bus_message *m, uint64_t cookie) { } } -static int message_from_header( +int bus_message_from_header( sd_bus *bus, void *header, size_t header_accessible, @@ -562,7 +562,7 @@ int bus_message_from_malloc( size_t sz; int r; - r = message_from_header( + r = bus_message_from_header( bus, buffer, length, /* in this case the initial bytes and the final bytes are the same */ buffer, length, @@ -1277,7 +1277,7 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message * return 0; } -static struct bus_body_part *message_append_part(sd_bus_message *m) { +struct bus_body_part *message_append_part(sd_bus_message *m) { struct bus_body_part *part; assert(m); @@ -5705,6 +5705,388 @@ static int message_parse_fields(sd_bus_message *m) { return 0; } +int bus_message_parse_fields(sd_bus_message *m) { + size_t ri; + int r; + uint32_t unix_fds = 0; + bool unix_fds_set = false; + void *offsets = NULL; + unsigned n_offsets = 0; + size_t sz = 0; + unsigned i = 0; + + assert(m); + + if (BUS_MESSAGE_IS_GVARIANT(m)) { + char *p; + + /* Read the signature from the end of the body variant first */ + sz = bus_gvariant_determine_word_size(BUS_MESSAGE_SIZE(m), 0); + if (m->footer_accessible < 1 + sz) + return -EBADMSG; + + p = (char*) m->footer + m->footer_accessible - (1 + sz); + for (;;) { + if (p < (char*) m->footer) + return -EBADMSG; + + if (*p == 0) { + _cleanup_free_ char *k = NULL; + size_t l; + + /* We found the beginning of the signature + * string, yay! We require the body to be a + * structure, so verify it and then strip the + * opening/closing brackets. */ + + l = (char*) m->footer + m->footer_accessible - p - (1 + sz); + if (l < 2 || + p[1] != SD_BUS_TYPE_STRUCT_BEGIN || + p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END) + return -EBADMSG; + + k = memdup_suffix0(p + 1 + 1, l - 2); + if (!k) + return -ENOMEM; + + if (!signature_is_valid(k, true)) + return -EBADMSG; + + free_and_replace(m->root_container.signature, k); + break; + } + + p--; + } + + /* Calculate the actual user body size, by removing + * the trailing variant signature and struct offset + * table */ + m->user_body_size = m->body_size - ((char*) m->footer + m->footer_accessible - p); + + /* Pull out the offset table for the fields array */ + sz = bus_gvariant_determine_word_size(m->fields_size, 0); + if (sz > 0) { + size_t framing; + void *q; + + ri = m->fields_size - sz; + r = message_peek_fields(m, &ri, 1, sz, &q); + if (r < 0) + return r; + + framing = bus_gvariant_read_word_le(q, sz); + if (framing >= m->fields_size - sz) + return -EBADMSG; + if ((m->fields_size - framing) % sz != 0) + return -EBADMSG; + + ri = framing; + r = message_peek_fields(m, &ri, 1, m->fields_size - framing, &offsets); + if (r < 0) + return r; + + n_offsets = (m->fields_size - framing) / sz; + } + } else + m->user_body_size = m->body_size; + + ri = 0; + while (ri < m->fields_size) { + _cleanup_free_ char *sig = NULL; + const char *signature; + uint64_t field_type; + size_t item_size = (size_t) -1; + + if (BUS_MESSAGE_IS_GVARIANT(m)) { + uint64_t *u64; + + if (i >= n_offsets) + break; + + if (i == 0) + ri = 0; + else + ri = ALIGN_TO(bus_gvariant_read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8); + + r = message_peek_fields(m, &ri, 8, 8, (void**) &u64); + if (r < 0) + return r; + + field_type = BUS_MESSAGE_BSWAP64(m, *u64); + } else { + uint8_t *u8; + + r = message_peek_fields(m, &ri, 8, 1, (void**) &u8); + if (r < 0) + return r; + + field_type = *u8; + } + + if (BUS_MESSAGE_IS_GVARIANT(m)) { + size_t where, end; + char *b; + void *q; + + end = bus_gvariant_read_word_le((uint8_t*) offsets + i*sz, sz); + + if (end < ri) + return -EBADMSG; + + where = ri = ALIGN_TO(ri, 8); + item_size = end - ri; + r = message_peek_fields(m, &where, 1, item_size, &q); + if (r < 0) + return r; + + b = memrchr(q, 0, item_size); + if (!b) + return -EBADMSG; + + sig = memdup_suffix0(b+1, item_size - (b+1-(char*) q)); + if (!sig) + return -ENOMEM; + + signature = sig; + item_size = b - (char*) q; + } else { + r = message_peek_field_signature(m, &ri, 0, &signature); + if (r < 0) + return r; + } + + switch (field_type) { + + case _BUS_MESSAGE_HEADER_INVALID: + return -EBADMSG; + + case BUS_MESSAGE_HEADER_PATH: + + if (m->path) + return -EBADMSG; + + if (!streq(signature, "o")) + return -EBADMSG; + + r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path); + break; + + case BUS_MESSAGE_HEADER_INTERFACE: + + if (m->interface) + return -EBADMSG; + + if (!streq(signature, "s")) + return -EBADMSG; + + r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface); + break; + + case BUS_MESSAGE_HEADER_MEMBER: + + if (m->member) + return -EBADMSG; + + if (!streq(signature, "s")) + return -EBADMSG; + + r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member); + break; + + case BUS_MESSAGE_HEADER_ERROR_NAME: + + if (m->error.name) + return -EBADMSG; + + if (!streq(signature, "s")) + return -EBADMSG; + + r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name); + if (r >= 0) + m->error._need_free = -1; + + break; + + case BUS_MESSAGE_HEADER_DESTINATION: + + if (m->destination) + return -EBADMSG; + + if (!streq(signature, "s")) + return -EBADMSG; + + r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination); + break; + + case BUS_MESSAGE_HEADER_SENDER: + + if (m->sender) + return -EBADMSG; + + if (!streq(signature, "s")) + return -EBADMSG; + + r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender); + + if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) { + m->creds.unique_name = (char*) m->sender; + m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask; + } + + break; + + case BUS_MESSAGE_HEADER_SIGNATURE: { + const char *s; + char *c; + + if (BUS_MESSAGE_IS_GVARIANT(m)) /* only applies to dbus1 */ + return -EBADMSG; + + if (m->root_container.signature) + return -EBADMSG; + + if (!streq(signature, "g")) + return -EBADMSG; + + r = message_peek_field_signature(m, &ri, item_size, &s); + if (r < 0) + return r; + + c = strdup(s); + if (!c) + return -ENOMEM; + + free_and_replace(m->root_container.signature, c); + break; + } + + case BUS_MESSAGE_HEADER_REPLY_SERIAL: + + if (m->reply_cookie != 0) + return -EBADMSG; + + if (BUS_MESSAGE_IS_GVARIANT(m)) { + /* 64bit on dbus2 */ + + if (!streq(signature, "t")) + return -EBADMSG; + + r = message_peek_field_uint64(m, &ri, item_size, &m->reply_cookie); + if (r < 0) + return r; + } else { + /* 32bit on dbus1 */ + uint32_t serial; + + if (!streq(signature, "u")) + return -EBADMSG; + + r = message_peek_field_uint32(m, &ri, item_size, &serial); + if (r < 0) + return r; + + m->reply_cookie = serial; + } + + if (m->reply_cookie == 0) + return -EBADMSG; + + break; + + case BUS_MESSAGE_HEADER_UNIX_FDS: + if (unix_fds_set) + return -EBADMSG; + + if (!streq(signature, "u")) + return -EBADMSG; + + r = message_peek_field_uint32(m, &ri, item_size, &unix_fds); + if (r < 0) + return -EBADMSG; + + unix_fds_set = true; + break; + + default: + if (!BUS_MESSAGE_IS_GVARIANT(m)) + r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature); + } + + if (r < 0) + return r; + + i++; + } + + if (m->n_fds != unix_fds) + return -EBADMSG; + + switch (m->header->type) { + + case SD_BUS_MESSAGE_SIGNAL: + if (!m->path || !m->interface || !m->member) + return -EBADMSG; + + if (m->reply_cookie != 0) + return -EBADMSG; + + break; + + case SD_BUS_MESSAGE_METHOD_CALL: + + if (!m->path || !m->member) + return -EBADMSG; + + if (m->reply_cookie != 0) + return -EBADMSG; + + break; + + case SD_BUS_MESSAGE_METHOD_RETURN: + + if (m->reply_cookie == 0) + return -EBADMSG; + break; + + case SD_BUS_MESSAGE_METHOD_ERROR: + + if (m->reply_cookie == 0 || !m->error.name) + return -EBADMSG; + break; + } + + /* Refuse non-local messages that claim they are local */ + if (streq_ptr(m->path, "/org/freedesktop/DBus/Local")) + return -EBADMSG; + if (streq_ptr(m->interface, "org.freedesktop.DBus.Local")) + return -EBADMSG; + if (streq_ptr(m->sender, "org.freedesktop.DBus.Local")) + return -EBADMSG; + + m->root_container.end = m->user_body_size; + + if (BUS_MESSAGE_IS_GVARIANT(m)) { + r = build_struct_offsets( + m, + m->root_container.signature, + m->user_body_size, + &m->root_container.item_size, + &m->root_container.offsets, + &m->root_container.n_offsets); + if (r == -EINVAL) + return -EBADMSG; + if (r < 0) + return r; + } + + /* Try to read the error message, but if we can't it's a non-issue */ + if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR) + (void) sd_bus_message_read(m, "s", &m->error.message); + + return 0; +} + _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) { assert_return(m, -EINVAL); assert_return(destination, -EINVAL); diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h index 62a019ff2e..b685dae901 100644 --- a/src/libsystemd/sd-bus/bus-message.h +++ b/src/libsystemd/sd-bus/bus-message.h @@ -76,6 +76,7 @@ struct sd_bus_message { usec_t monotonic; usec_t realtime; uint64_t seqnum; + int64_t priority; uint64_t verify_destination_id; bool sealed:1; @@ -185,6 +186,19 @@ static inline bool BUS_MESSAGE_IS_GVARIANT(sd_bus_message *m) { int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz); +int bus_message_from_header( + sd_bus *bus, + void *header, + size_t header_accessible, + void *footer, + size_t footer_accessible, + size_t message_size, + int *fds, + size_t n_fds, + const char *label, + size_t extra, + sd_bus_message **ret); + int bus_message_from_malloc( sd_bus *bus, void *buffer, @@ -197,6 +211,10 @@ int bus_message_from_malloc( int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str); int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv); +int bus_message_parse_fields(sd_bus_message *m); + +struct bus_body_part *message_append_part(sd_bus_message *m); + #define MESSAGE_FOREACH_PART(part, i, m) \ for ((i) = 0, (part) = &(m)->body; (i) < (m)->n_body_parts; (i)++, (part) = (part)->next) diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 4e677fc4e5..b8cf7b91cd 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1111,7 +1111,7 @@ static int parse_container_kernel_address(sd_bus *b, const char **p, char **guid return -EINVAL; if (machine) { - if (!machine_name_is_valid(machine)) + if (!hostname_is_valid(machine, 0)) return -EINVAL; free(b->machine); @@ -2289,7 +2289,7 @@ static int dispatch_wqueue(sd_bus *bus) { return ret; } -static int bus_read_message(sd_bus *bus) { +static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) { assert(bus); if (bus->is_kernel) @@ -2319,7 +2319,7 @@ static void rqueue_drop_one(sd_bus *bus, size_t i) { bus->rqueue_size--; } -static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) { +static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) { int r, ret = 0; assert(bus); @@ -2335,7 +2335,7 @@ static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) { } /* Try to read a new message */ - r = bus_read_message(bus); + r = bus_read_message(bus, hint_priority, priority); if (r < 0) return r; if (r == 0) { @@ -2700,7 +2700,7 @@ _public_ int sd_bus_call( i++; } - r = bus_read_message(bus); + r = bus_read_message(bus, false, 0); if (r < 0) { if (ERRNO_IS_DISCONNECT(r)) { bus_enter_closing(bus); @@ -3247,7 +3247,7 @@ static int dispatch_track(sd_bus *bus) { return 1; } -static int process_running(sd_bus *bus, sd_bus_message **ret) { +static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; @@ -3266,7 +3266,7 @@ static int process_running(sd_bus *bus, sd_bus_message **ret) { if (r != 0) goto null_message; - r = dispatch_rqueue(bus, &m); + r = dispatch_rqueue(bus, hint_priority, priority, &m); if (r < 0) return r; if (!m) @@ -3452,7 +3452,7 @@ finish: return r; } -static int bus_process_internal(sd_bus *bus, sd_bus_message **ret) { +static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) { int r; /* Returns 0 when we didn't do anything. This should cause the @@ -3492,7 +3492,7 @@ static int bus_process_internal(sd_bus *bus, sd_bus_message **ret) { case BUS_RUNNING: case BUS_HELLO: - r = process_running(bus, ret); + r = process_running(bus, hint_priority, priority, ret); if (r >= 0) return r; @@ -3519,11 +3519,11 @@ static int bus_process_internal(sd_bus *bus, sd_bus_message **ret) { } _public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) { - return bus_process_internal(bus, ret); + return bus_process_internal(bus, false, 0, ret); } _public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) { - return bus_process_internal(bus, ret); + return bus_process_internal(bus, true, priority, ret); } static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c index 9ec49b2276..ce2a2bc62f 100644 --- a/src/libsystemd/sd-bus/test-bus-benchmark.c +++ b/src/libsystemd/sd-bus/test-bus-benchmark.c @@ -11,6 +11,7 @@ #include "constants.h" #include "fd-util.h" #include "missing_resource.h" +#include "process-util.h" #include "string-util.h" #include "tests.h" #include "time-util.h" diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c index 47b1752360..fb18166420 100644 --- a/src/libsystemd/sd-bus/test-bus-gvariant.c +++ b/src/libsystemd/sd-bus/test-bus-gvariant.c @@ -13,7 +13,6 @@ #include "bus-message.h" #include "macro.h" #include "tests.h" -#include "util.h" TEST(bus_gvariant_is_fixed_size) { assert_se(bus_gvariant_is_fixed_size("") > 0); diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index edbabbad85..6c8b19f8d5 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -21,6 +21,7 @@ #include "bus-error.h" #include "bus-internal.h" #include "bus-locator.h" +#include "bus-util.h" #include "cap-list.h" #include "capability-util.h" #include "cgroup-setup.h" @@ -353,6 +354,7 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_ static int export_legacy_dbus_address( pam_handle_t *handle, + uid_t uid, const char *runtime) { const char *s; @@ -373,7 +375,7 @@ static int export_legacy_dbus_address( if (is_kdbus_available()) { if (asprintf(&t, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, uid, runtime) < 0) - goto error; + return pam_log_oom(handle); } else { s = strjoina(runtime, "/bus"); if (access(s, F_OK) < 0) @@ -768,7 +770,7 @@ static int configure_runtime_directory( if (r != PAM_SUCCESS) return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to set runtime dir: @PAMERR@"); - return export_legacy_dbus_address(handle, rt); + return export_legacy_dbus_address(handle, ur->uid, rt); } static uint64_t pick_default_capability_ambient_set( diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 72214799e0..a61c24930f 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -501,13 +501,13 @@ int mount_sysfs(const char *dest, MountSettingsMask mount_settings) { if (rmdir(full) < 0) return log_error_errno(errno, "Failed to remove %s: %m", full); - x = prefix_roota(top, "/fs/kdbus"); + const char *x = prefix_roota(top, "/fs/kdbus"); (void) mkdir_p(x, 0755); /* Create mountpoint for cgroups. Otherwise we are not allowed since we * remount /sys read-only. */ - const char *x = prefix_roota(top, "/fs/cgroup"); + x = prefix_roota(top, "/fs/cgroup"); (void) mkdir_p(x, 0755); return mount_nofollow_verbose(LOG_ERR, NULL, top, NULL, diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index a1de6040fa..ede2b476f3 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -229,7 +229,7 @@ int bus_connect_system_systemd(sd_bus **ret_bus) { r = sd_bus_start(bus); if (r >= 0) { - *_bus = bus; + *ret_bus = bus; bus = NULL; return 0; } @@ -277,7 +277,7 @@ int bus_connect_user_systemd(sd_bus **ret_bus) { r = sd_bus_start(bus); if (r >= 0) { - *_bus = bus; + *ret_bus = bus; bus = NULL; return 0; } @@ -561,7 +561,7 @@ bool is_kdbus_wanted(void) { if (wanted < 0) { bool b; - if (proc_cmdline_get_bool("kdbus", &b) > 0) { + if (proc_cmdline_get_bool("kdbus", 0, &b) > 0) { wanted = b; goto finish; } |