Fix: runas worker attempts to send invalid fd to master
[lttng-tools.git] / src / common / runas.c
index 4a8536c6de0eb1063ed9b4f351d1f40c37355c50..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,6 +403,10 @@ 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");
@@ -466,6 +477,9 @@ int cleanup_received_fd(enum run_as_cmd cmd, int fd)
                return 0;
        }
 
+       if (fd < 0) {
+               return 0;
+       }
        ret = close(fd);
        if (ret < 0) {
                PERROR("close error");
@@ -488,6 +502,9 @@ int handle_one_cmd(struct run_as_worker *worker)
        run_as_fct cmd;
        uid_t prev_euid;
 
+       memset(&sendret, 0, sizeof(sendret));
+       sendret.fd = -1;
+
        /*
         * Stage 1: Receive run_as_data struct from the master.
         * The structure contains the command type and all the parameters needed for
@@ -528,6 +545,8 @@ int handle_one_cmd(struct run_as_worker *worker)
        if (data.gid != getegid()) {
                ret = setegid(data.gid);
                if (ret < 0) {
+                       sendret._error = true;
+                       sendret._errno = errno;
                        PERROR("setegid");
                        goto write_return;
                }
@@ -535,6 +554,8 @@ int handle_one_cmd(struct run_as_worker *worker)
        if (data.uid != prev_euid) {
                ret = seteuid(data.uid);
                if (ret < 0) {
+                       sendret._error = true;
+                       sendret._errno = errno;
                        PERROR("seteuid");
                        goto write_return;
                }
@@ -713,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
         */
@@ -799,7 +825,6 @@ int run_as(enum run_as_cmd cmd, struct run_as_data *data,
                        DBG("Socket closed unexpectedly... "
                                        "Restarting the worker process");
                        ret = run_as_restart_worker(global_worker);
-
                        if (ret == -1) {
                                ERR("Failed to restart worker process.");
                                goto err;
@@ -915,6 +940,9 @@ int run_as_extract_elf_symbol_offset(int fd, const char* function,
        struct run_as_data data;
        struct run_as_ret ret;
 
+       memset(&data, 0, sizeof(data));
+       memset(&ret, 0, sizeof(ret));
+
        DBG3("extract_elf_symbol_offset() on fd=%d and function=%s "
                "with for uid %d and gid %d", fd, function, (int) uid, (int) gid);
 
@@ -944,6 +972,9 @@ int run_as_extract_sdt_probe_offsets(int fd, const char* provider_name,
        struct run_as_data data;
        struct run_as_ret ret;
 
+       memset(&data, 0, sizeof(data));
+       memset(&ret, 0, sizeof(ret));
+
        DBG3("extract_sdt_probe_offsets() on fd=%d, probe_name=%s and "
                "provider_name=%s with for uid %d and gid %d", fd, probe_name,
                provider_name, (int) uid, (int) gid);
This page took 0.023933 seconds and 4 git commands to generate.