X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-socket.c;h=145f454d5d3cdcbe5d3c4e0eb7c556f8fa6a1a2a;hb=23e97f7d9274b90fb0e1664945dc6259fdae6d39;hp=b9ef7c03720ea6f58e5d88961d7015ecbafc7f9f;hpb=9ab32f9daa9601250f183a694586712654be2ffe;p=elogind.git diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index b9ef7c037..145f454d5 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -235,7 +235,7 @@ static int verify_external_token(sd_bus *b, const char *p, size_t l) { * the owner of this bus wanted authentication he should have * checked SO_PEERCRED before even creating the bus object. */ - if (!b->ucred_valid) + if (!b->anonymous_auth && !b->ucred_valid) return 0; if (l <= 0) @@ -258,7 +258,9 @@ static int verify_external_token(sd_bus *b, const char *p, size_t l) { if (r < 0) return 0; - if (u != b->ucred.uid) + /* We ignore the passed value if anonymous authentication is + * on anyway. */ + if (!b->anonymous_auth && u != b->ucred.uid) return 0; return 1; @@ -311,13 +313,16 @@ static int bus_socket_auth_verify_server(sd_bus *b) { assert(b); - if (b->rbuffer_size < 3) + if (b->rbuffer_size < 1) return 0; /* First char must be a NUL byte */ if (*(char*) b->rbuffer != 0) return -EIO; + if (b->rbuffer_size < 3) + return 0; + /* Begin with the first line */ if (b->auth_rbegin <= 0) b->auth_rbegin = 1; @@ -450,7 +455,7 @@ static int bus_socket_read_auth(sd_bus *b) { if (r != 0) return r; - n = MAX(256, b->rbuffer_size * 2); + n = MAX(256u, b->rbuffer_size * 2); if (n > BUS_AUTH_SIZE_MAX) n = BUS_AUTH_SIZE_MAX; @@ -508,16 +513,23 @@ static int bus_socket_read_auth(sd_bus *b) { cmsg->cmsg_type == SCM_CREDENTIALS && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) { - memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred)); - b->ucred_valid = true; + /* 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); - memcpy(&b->label, CMSG_DATA(cmsg), l); - b->label[l] = 0; + if (l > 0) { + memcpy(&b->label, CMSG_DATA(cmsg), l); + b->label[l] = 0; + } } } } @@ -531,6 +543,7 @@ static int bus_socket_read_auth(sd_bus *b) { static int bus_socket_setup(sd_bus *b) { int enable; + socklen_t l; assert(b); @@ -544,6 +557,11 @@ static int bus_socket_setup(sd_bus *b) { fd_inc_rcvbuf(b->input_fd, 1024*1024); fd_inc_sndbuf(b->output_fd, 1024*1024); + /* Get the peer for socketpair() sockets */ + l = sizeof(b->ucred); + if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred)) + b->ucred_valid = b->ucred.pid > 0; + return 0; } @@ -935,16 +953,22 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { cmsg->cmsg_type == SCM_CREDENTIALS && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) { - memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred)); - bus->ucred_valid = true; + /* 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); - memcpy(&bus->label, CMSG_DATA(cmsg), l); - bus->label[l] = 0; + if (l > 0) { + memcpy(&bus->label, CMSG_DATA(cmsg), l); + bus->label[l] = 0; + } } } } @@ -962,16 +986,14 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { int bus_socket_process_opening(sd_bus *b) { int error = 0; socklen_t slen = sizeof(error); - struct pollfd p; + struct pollfd p = { + .fd = b->output_fd, + .events = POLLOUT, + }; int r; - assert(b); assert(b->state == BUS_OPENING); - zero(p); - p.fd = b->output_fd; - p.events = POLLOUT; - r = poll(&p, 1, 0); if (r < 0) return -errno;