From 93e713929081a6bbf859adaafc9b7e5415321516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Sat, 8 Sep 2018 16:16:33 +0000 Subject: [PATCH] Remove execution functionality for possible security issues --- lewdfingerd.c | 142 +------------------------------------------------- 1 file changed, 1 insertion(+), 141 deletions(-) diff --git a/lewdfingerd.c b/lewdfingerd.c index fd60f5d..d186755 100644 --- a/lewdfingerd.c +++ b/lewdfingerd.c @@ -146,139 +146,7 @@ ssize_t writeall_str(int fd, const char *s) { return writeall(fd, s, strlen(s)); } -bool execute_finger_response(int sock, const char *finger_response_file) { - int pipes[2]; - if(pipe(pipes) != 0) { - log_perror("pipe"); - return false; - } - - pid_t child = fork(); - if(child < 0) { - log_perror("fork"); - return false; - } - - if(child == 0) { - // Child - - // Close unneeded fds - for(size_t i = 0; i < num_listens; i++) { - close(listens[num_listens].fd); - } - close(sock); - close(pipes[0]); - - // Set up stdout - if(dup2(pipes[1], STDOUT_FILENO) < 0) { - log_perror("dup2"); - _exit(1); - } - - // execv's types require this cast - char *argv[] = {(char*) finger_response_file, NULL}; - execv(finger_response_file, argv); - - log_perror("execv"); - _exit(1); - } else { - // Parent - - // Close unneeded fds - close(pipes[1]); - - struct timespec start_time; - // Doesn't seem this could fail in our configuration - clock_gettime(CLOCK_MONOTONIC, &start_time); - - char iobuf[1024]; - - struct pollfd pipe_poll = {.fd = pipes[0], .events = POLLIN}; - for(;;) { - // Check the child is still running - int status; - waitpid(child, &status, WNOHANG); - if(WIFEXITED(status) || WIFSIGNALED(status)) { - // Child quit - if(WIFSIGNALED(status)) { - log_error("Child died of signal %i\n", WTERMSIG(status)); - } else if(WIFEXITED(status) && WEXITSTATUS(status) != 0) { - log_error("Child exited with nonzero return code %i\n", WEXITSTATUS(status)); - } - break; - } - - struct timespec current_time; - // See previous usage of this - clock_gettime(CLOCK_MONOTONIC, ¤t_time); - - time_t secs_passed = current_time.tv_sec - start_time.tv_sec; - long ns_passed = current_time.tv_nsec - start_time.tv_nsec; - int ms_passed = secs_passed * 1000 + ns_passed / 1000; - // Timeout of 5s - int ms_remaining = 5000 - ms_passed; - - if(ms_remaining <= 0) { - log_error("Child ran too long\n"); - if(kill(child, SIGKILL)) { - log_perror("kill"); - } - - // Wait to get rid of the zombie - waitpid(child, NULL, 0); - - if(writeall_str(sock, "Timeout\r\n") < 0) { - log_perror("writeall_str"); - close(pipes[0]); - return false; - } - - break; - } - - int amount_ready = poll(&pipe_poll, 1, ms_remaining); - - for(int i = 0; i < amount_ready; i++) { - if(pipe_poll.revents & POLLIN) { - ssize_t amount_read = read(pipes[0], iobuf, sizeof(iobuf)); - if(amount_read < 0) { - log_perror("read"); - break; - } - - char *newline_location = memchr(iobuf, '\n', amount_read); - if(newline_location == NULL) { - // No newline, write entire buffer - if(writeall(sock, iobuf, amount_read) < 0) { - log_perror("writeall"); - break; - } - } else { - // Newline found. Write stuff before it and \r\n - if(writeall(sock, iobuf, newline_location - iobuf) < 0 || writeall_str(sock, "\r\n") < 0) { - log_perror("writeall / writeall_str"); - break; - } - - // Write the part after it - char *part_after_nl = newline_location + 1; - size_t part_after_nl_length = amount_read - (part_after_nl - iobuf); - if(writeall(sock, part_after_nl, part_after_nl_length) < 0) { - log_perror("writeall"); - break; - } - } - } - } - } - - close(pipes[0]); - } - - return true; -} - -bool read_finger_response(int sock, const char *finger_response_file) { +bool handle_finger_response(int sock, const char *finger_response_file) { FILE *f = fopen(finger_response_file, "r"); if(f == NULL) { log_perror("fopen"); @@ -314,14 +182,6 @@ bool read_finger_response(int sock, const char *finger_response_file) { return true; } -bool handle_finger_response(int sock, const char *finger_response_file) { - if(access(finger_response_file, X_OK) == 0) { - return execute_finger_response(sock, finger_response_file); - } else { - return read_finger_response(sock, finger_response_file); - } -} - void handle_userlist(int sock, bool force_multiline) { // Go over users' home dirs and see if .finger-response is present bool first_line = true;