From 38069abf612962436357caec1c17e7f218f1a530 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Thu, 6 Sep 2018 18:11:25 -0400 Subject: [PATCH] Fix: runas worker attempts to send invalid fd to master MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/common/runas.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/common/runas.c b/src/common/runas.c index 0a5884826..016cefe28 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -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 */ -- 2.34.1