diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-04-01 03:25:31 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-04-01 03:29:30 +0200 |
commit | ea8f194f4b402774aafb9bc3c3ea1c0f288f12a7 (patch) | |
tree | d77e7098943554eebe6d03da9d5bca50e97f85cb /src/libsystemd-bus/bus-socket.c | |
parent | 2b4ac8896bdc6cc5159088d7d208559d53caacf3 (diff) |
bus: be more careful when determining credential data
As it turns out SCM_CREDENTIALS is not always supported on socketpair(),
so let's also try SO_PEERCRED then.
Diffstat (limited to 'src/libsystemd-bus/bus-socket.c')
-rw-r--r-- | src/libsystemd-bus/bus-socket.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 82e683a957..5b5a731233 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -513,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; + } } } } @@ -536,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); @@ -549,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; } @@ -940,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; + } } } } |