X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibelogind%2Fsd-bus%2Fbus-socket.c;h=322d57ddbba43437348b713b36a72454d3081591;hb=f95b4196af441a62980cc2ec1e72993e2a2521b6;hp=6a55f9bfb48554bce9aa4701481c999e6acb3ead;hpb=18ecad86637d1caff5486ce8f8dcfa49996e3f07;p=elogind.git diff --git a/src/libelogind/sd-bus/bus-socket.c b/src/libelogind/sd-bus/bus-socket.c index 6a55f9bfb..322d57ddb 100644 --- a/src/libelogind/sd-bus/bus-socket.c +++ b/src/libelogind/sd-bus/bus-socket.c @@ -24,12 +24,13 @@ #include #include +#include "sd-daemon.h" #include "util.h" #include "macro.h" #include "missing.h" #include "utf8.h" -#include "sd-daemon.h" #include "formats-util.h" +#include "signal-util.h" #include "sd-bus.h" #include "bus-socket.h" @@ -177,7 +178,7 @@ static int bus_socket_auth_verify_client(sd_bus *b) { /* We expect two response lines: "OK" and possibly * "AGREE_UNIX_FD" */ - e = memmem(b->rbuffer, b->rbuffer_size, "\r\n", 2); + e = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2); if (!e) return 0; @@ -492,18 +493,15 @@ static int bus_socket_auth_verify(sd_bus *b) { static int bus_socket_read_auth(sd_bus *b) { struct msghdr mh; - struct iovec iov; + struct iovec iov = {}; size_t n; ssize_t k; int r; 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); @@ -527,7 +525,6 @@ static int bus_socket_read_auth(sd_bus *b) { b->rbuffer = p; - zero(iov); iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size; iov.iov_len = n - b->rbuffer_size; @@ -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); @@ -808,23 +784,21 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { if (bus->prefer_writev) k = writev(bus->output_fd, iov, m->n_iovec); else { - struct msghdr mh; - zero(mh); + struct msghdr mh = { + .msg_iov = iov, + .msg_iovlen = m->n_iovec, + }; if (m->n_fds > 0) { struct cmsghdr *control; - control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds)); - mh.msg_control = control; + mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds)); + mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds); control->cmsg_level = SOL_SOCKET; control->cmsg_type = SCM_RIGHTS; - mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds); memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds); } - mh.msg_iov = iov; - mh.msg_iovlen = m->n_iovec; - k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL); if (k < 0 && errno == ENOTSOCK) { bus->prefer_writev = true; @@ -915,8 +889,7 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { r = bus_message_from_malloc(bus, bus->rbuffer, size, bus->fds, bus->n_fds, - !bus->bus_client && bus->ucred_valid ? &bus->ucred : NULL, - !bus->bus_client && !isempty(bus->label) ? bus->label : NULL, + NULL, &t); if (r < 0) { free(b); @@ -936,18 +909,15 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { int bus_socket_read_message(sd_bus *bus) { struct msghdr mh; - struct iovec iov; + struct iovec iov = {}; ssize_t k; size_t need; int r; 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); @@ -966,7 +936,6 @@ int bus_socket_read_message(sd_bus *bus) { bus->rbuffer = b; - zero(iov); iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size; iov.iov_len = need - bus->rbuffer_size; @@ -994,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; @@ -1019,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);