X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-socket.c;h=1365092d736fa3f9eaadcfe8824c40d1a8c1c4aa;hp=4635da4b9ea436d98ee6735fb7cc5be5a12f80a4;hb=9f97c93671554dd3c46588b7c31031d26440ba34;hpb=c91cb83c4dbc9a95a0a2a38e7028e0a7f4af3b35 diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 4635da4b9..1365092d7 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -88,23 +88,33 @@ static int bus_message_setup_iovec(sd_bus_message *m) { m->iovec = m->iovec_fixed; else { m->iovec = new(struct iovec, n); - if (!m->iovec) - return -ENOMEM; + if (!m->iovec) { + r = -ENOMEM; + goto fail; + } } r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m)); if (r < 0) - return r; + goto fail; MESSAGE_FOREACH_PART(part, i, m) { + r = bus_body_part_map(part); + if (r < 0) + goto fail; + r = append_iovec(m, part->data, part->size); if (r < 0) - return r; + goto fail; } assert(n == m->n_iovec); return 0; + +fail: + m->poisoned = true; + return r; } bool bus_socket_auth_needs_write(sd_bus *b) { @@ -171,7 +181,7 @@ static int bus_socket_auth_verify_client(sd_bus *b) { if (!e) return 0; - if (b->negotiate_fds) { + if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) { f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2); if (!f) return 0; @@ -454,7 +464,7 @@ static int bus_socket_auth_verify_server(sd_bus *b) { r = bus_socket_auth_write_ok(b); } } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) { - if (b->auth == _BUS_AUTH_INVALID || !b->negotiate_fds) + if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD)) r = bus_socket_auth_write(b, "ERROR\r\n"); else { b->can_fds = true; @@ -590,7 +600,7 @@ static int bus_socket_read_auth(sd_bus *b) { return 1; } -static int bus_socket_setup(sd_bus *b) { +int bus_socket_setup(sd_bus *b) { int enable; socklen_t l; @@ -600,6 +610,8 @@ static int bus_socket_setup(sd_bus *b) { * socket, just in case. */ enable = !b->bus_client; setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)); + + enable = !b->bus_client && (b->attach_flags & KDBUS_ATTACH_SECLABEL); setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable)); /* Increase the buffers to a MB */ @@ -611,6 +623,10 @@ static int bus_socket_setup(sd_bus *b) { if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred)) b->ucred_valid = b->ucred.pid > 0; + b->is_kernel = false; + b->message_version = 1; + b->message_endian = 0; + return 0; } @@ -641,7 +657,7 @@ static int bus_socket_start_auth_client(sd_bus *b) { if (!b->auth_buffer) return -ENOMEM; - if (b->negotiate_fds) + if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n"; else auth_suffix = "\r\nBEGIN\r\n"; @@ -656,18 +672,18 @@ static int bus_socket_start_auth_client(sd_bus *b) { return bus_socket_write_auth(b); } -static int bus_socket_start_auth(sd_bus *b) { +int bus_socket_start_auth(sd_bus *b) { assert(b); b->state = BUS_AUTHENTICATING; b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT; if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0) - b->negotiate_fds = false; + b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD; if (b->output_fd != b->input_fd) if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0) - b->negotiate_fds = false; + b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD; if (b->is_server) return bus_socket_read_auth(b); @@ -753,6 +769,10 @@ int bus_socket_exec(sd_bus *b) { close_nointr_nofail(s[1]); b->output_fd = b->input_fd = s[0]; + r = bus_socket_setup(b); + if (r < 0) + return r; + return bus_socket_start_auth(b); } @@ -862,10 +882,10 @@ static int bus_socket_read_message_need(sd_bus *bus, size_t *need) { b = ((const uint32_t*) bus->rbuffer)[3]; e = ((const uint8_t*) bus->rbuffer)[0]; - if (e == SD_BUS_LITTLE_ENDIAN) { + if (e == BUS_LITTLE_ENDIAN) { a = le32toh(a); b = le32toh(b); - } else if (e == SD_BUS_BIG_ENDIAN) { + } else if (e == BUS_BIG_ENDIAN) { a = be32toh(a); b = be32toh(b); } else @@ -879,16 +899,19 @@ static int bus_socket_read_message_need(sd_bus *bus, size_t *need) { return 0; } -static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) { +static int bus_socket_make_message(sd_bus *bus, size_t size) { sd_bus_message *t; void *b; int r; assert(bus); - assert(m); assert(bus->rbuffer_size >= size); assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO); + r = bus_rqueue_make_room(bus); + if (r < 0) + return r; + if (bus->rbuffer_size > size) { b = memdup((const uint8_t*) bus->rbuffer + size, bus->rbuffer_size - size); @@ -897,7 +920,8 @@ static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) } else b = NULL; - r = bus_message_from_malloc(bus->rbuffer, size, + r = bus_message_from_malloc(bus, + bus->rbuffer, size, bus->fds, bus->n_fds, bus->ucred_valid ? &bus->ucred : NULL, bus->label[0] ? bus->label : NULL, @@ -913,11 +937,12 @@ static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) bus->fds = NULL; bus->n_fds = 0; - *m = t; + bus->rqueue[bus->rqueue_size++] = t; + return 1; } -int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { +int bus_socket_read_message(sd_bus *bus) { struct msghdr mh; struct iovec iov; ssize_t k; @@ -934,7 +959,6 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { bool handle_cmsg = false; assert(bus); - assert(m); assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO); r = bus_socket_read_message_need(bus, &need); @@ -942,7 +966,7 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { return r; if (bus->rbuffer_size >= need) - return bus_socket_make_message(bus, need, m); + return bus_socket_make_message(bus, need); b = realloc(bus->rbuffer, need); if (!b) @@ -1032,7 +1056,7 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { return r; if (bus->rbuffer_size >= need) - return bus_socket_make_message(bus, need, m); + return bus_socket_make_message(bus, need); return 1; }