Fix: runas worker attempts to send invalid fd to master
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 6 Sep 2018 22:11:25 +0000 (18:11 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 6 Sep 2018 22:14:34 +0000 (18:14 -0400)
Commands which return a file descriptor (i.e. RUN_AS_OPEN) attempt
to send the resulting file descriptor even on failure. However,
this is not permitted by the UNIX socket interface.

As a result, skip the reception of the file descriptor payload
when a command fails. The 'master' end is also adapted to skip
the reception of the file descriptor in the case of an error.

A check has also been added to ensure that the 'master' end does
not attempt to send invalid file descriptors to the worker process.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/common/runas.c

index 4bd356a0499f2119a227a69b324ab5248d7ba8a0..c4bb298bfab938735aba850bb163cefa1e0424cd 100644 (file)
@@ -329,7 +329,8 @@ int do_send_fd(int sock, int fd)
        ssize_t len;
 
        if (fd < 0) {
-               ERR("Invalid file description");
+               ERR("Attempt to send invalid file descriptor to master (fd = %i)", fd);
+               /* Return 0 as this is not a fatal error. */
                return 0;
        }
 
@@ -346,11 +347,6 @@ int do_recv_fd(int sock, int *fd)
 {
        ssize_t len;
 
-       if (*fd < 0) {
-               ERR("Invalid file description");
-               return 0;
-       }
-
        len = lttcomm_recv_fds_unix_sock(sock, fd, 1);
 
        if (!len) {
@@ -359,6 +355,12 @@ int do_recv_fd(int sock, int *fd)
                PERROR("lttcomm_recv_fds_unix_sock");
                return -1;
        }
+       if (*fd < 0) {
+               ERR("Invalid file descriptor received from worker (fd = %i)", *fd);
+               /* Return 0 as this is not a fatal error. */
+               return 0;
+       }
+
        return 0;
 }
 
@@ -375,6 +377,11 @@ int send_fd_to_worker(struct run_as_worker *worker, enum run_as_cmd cmd, int fd)
                return 0;
        }
 
+       if (fd < 0) {
+               ERR("Refusing to send invalid fd to worker (fd = %i)", fd);
+               return -1;
+       }
+
        ret = do_send_fd(worker->sockpair[0], fd);
        if (ret < 0) {
                PERROR("do_send_fd");
@@ -396,20 +403,21 @@ int send_fd_to_master(struct run_as_worker *worker, enum run_as_cmd cmd, int fd)
                return 0;
        }
 
+       if (fd < 0) {
+               DBG("Not sending file descriptor to master as it is invalid (fd = %i)", fd);
+               return 0;
+       }
        ret = do_send_fd(worker->sockpair[1], fd);
        if (ret < 0) {
                PERROR("do_send_fd error");
                ret = -1;
        }
 
-       if (fd < 0) {
-               goto end;
-       }
        ret_close = close(fd);
        if (ret_close < 0) {
                PERROR("close");
        }
-end:
+
        return ret;
 }
 
@@ -726,6 +734,11 @@ int run_as_cmd(struct run_as_worker *worker,
                goto end;
        }
 
+       if (ret_value->_error) {
+               /* Skip stage 5 on error as there will be no fd to receive. */
+               goto end;
+       }
+
        /*
         * Stage 5: Receive file descriptor if needed
         */
This page took 0.026338 seconds and 4 git commands to generate.