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=d7d3b4dac5aa2bea3c4b21e40de7f3edc4fb5423;hp=f43b7da05ca651fa158a07e850cf0531f4a840dc;hb=b57bdedc87c763aba1b5e8dc5396bfa3ac7d5086;hpb=9b29bb6853987bf6fef21531f69864fdfb39eb9a diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index f43b7da05..d7d3b4dac 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -83,34 +83,38 @@ static int bus_message_setup_iovec(sd_bus_message *m) { assert(!m->iovec); - n = 1 + !!m->fields + m->n_body_parts; + n = 1 + m->n_body_parts; if (n < ELEMENTSOF(m->iovec_fixed)) 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, sizeof(*m->header)); + r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m)); if (r < 0) - return r; + goto fail; - if (m->fields) { - r = append_iovec(m, m->fields, ALIGN8(m->header->fields_size)); + MESSAGE_FOREACH_PART(part, i, m) { + r = bus_body_part_map(part); if (r < 0) - return r; - } + goto fail; - MESSAGE_FOREACH_PART(part, i, m) { 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) { @@ -177,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; @@ -460,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; @@ -596,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; @@ -606,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 */ @@ -647,7 +653,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"; @@ -662,18 +668,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); @@ -885,16 +891,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); @@ -903,7 +912,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, @@ -919,11 +929,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; @@ -940,7 +951,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); @@ -948,7 +958,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) @@ -1038,7 +1048,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; }