chiark / gitweb /
libsystemd-bus: initalize handle_cmsg to false
[elogind.git] / src / libsystemd-bus / bus-socket.c
index 30e594243d5d62893182f30d21b1600cc22b84c4..1a0d9266f2727bc2eb9cc9c4934b47824319ca55 100644 (file)
@@ -313,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;
@@ -452,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;
@@ -510,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;
+                                }
                         }
                 }
         }
@@ -533,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);
 
@@ -546,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;
 }
 
@@ -861,7 +877,7 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
                             CMSG_SPACE(NAME_MAX)]; /*selinux label */
         } control;
         struct cmsghdr *cmsg;
-        bool handle_cmsg;
+        bool handle_cmsg = false;
 
         assert(bus);
         assert(m);
@@ -937,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;
+                                }
                         }
                 }
         }
@@ -964,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;