static int send_fd_to_worker(struct run_as_worker *worker, enum run_as_cmd cmd, int fd) { int ret = 0; switch (cmd) { case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS: case RUN_AS_MKDIRAT: case RUN_AS_MKDIRAT_RECURSIVE: break; default: 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"); ret = -1; } return ret; }
static int send_fd_to_master(struct run_as_worker *worker, enum run_as_cmd cmd, int fd) { int ret = 0, ret_close = 0; switch (cmd) { case RUN_AS_OPEN: break; default: 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; } ret_close = close(fd); if (ret_close < 0) { PERROR("close"); } return ret; }
/* * Return < 0 on error, 0 if OK, 1 on hangup. */ static int handle_one_cmd(struct run_as_worker *worker) { int ret = 0; struct run_as_data data; ssize_t readlen, writelen; struct run_as_ret sendret; run_as_fct cmd; uid_t prev_euid; /* Read data */ readlen = lttcomm_recv_unix_sock(worker->sockpair[1], &data, sizeof(data)); if (readlen == 0) { /* hang up */ ret = 1; goto end; } if (readlen < sizeof(data)) { PERROR("lttcomm_recv_unix_sock error"); ret = -1; goto end; } cmd = run_as_enum_to_fct(data.cmd); if (!cmd) { ret = -1; goto end; } prev_euid = getuid(); if (data.gid != getegid()) { ret = setegid(data.gid); if (ret < 0) { PERROR("setegid"); goto write_return; } } if (data.uid != prev_euid) { ret = seteuid(data.uid); if (ret < 0) { PERROR("seteuid"); goto write_return; } } /* * Also set umask to 0 for mkdir executable bit. */ umask(0); ret = (*cmd)(&data); write_return: sendret.ret = ret; sendret._errno = errno; /* send back return value */ writelen = lttcomm_send_unix_sock(worker->sockpair[1], &sendret, sizeof(sendret)); if (writelen < sizeof(sendret)) { PERROR("lttcomm_send_unix_sock error"); ret = -1; goto end; } ret = do_send_fd(worker, data.cmd, ret); if (ret) { PERROR("do_send_fd error"); ret = -1; goto end; } if (seteuid(prev_euid) < 0) { PERROR("seteuid"); ret = -1; goto end; } ret = 0; end: return ret; }