From 7310afccc11070fd4207a41881401d619dd113b1 Mon Sep 17 00:00:00 2001 From: Paul Crawford Date: Mon, 31 Jul 2017 16:36:10 +0100 Subject: [PATCH 09/10] Bugfix against watchdog configuration file corruption - Apply the bugfix/patch against watchdog configuration file corruption during runtime by Greg Vishnepolsky greg@armis.com - Modify from Greg's patch to include the permission mode and to declare the new fd variables immediately after the opening brace. - Greg provided the follow description: The following patch fixes a bug where writes/prints (out of a test binary) that are intended for stdout/stderr may instead be written to other files (like the watchdog configuration files). The bug lies in the call to "freopen" on "stdout" when the actual FD (1) for stdout had been previously closed by the daemon. Instead this FD could have been re-used (for instance, for opening watchdog configuration files). Thus any prints out of the daemon/test binaries will be erroneously written into it. --- src/test_binary.c | 13 +++++++++++-- src/watchdog.c | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/test_binary.c b/src/test_binary.c index 2211f9e..a58c107 100644 --- a/src/test_binary.c +++ b/src/test_binary.c @@ -3,6 +3,7 @@ #endif #include +#include #include #include #include @@ -258,16 +259,24 @@ int check_bin(char *tbinary, int timeout, int version) child_pid = fork(); if (!child_pid) { + int test_stdout_fd, test_stderr_fd; /* Don't want the stdout and stderr of our test program * to cause trouble, so make them go to their respective files */ strcpy(filename_buf, logdir); strcat(filename_buf, "/test-bin.stdout"); - if (!freopen(filename_buf, "a+", stdout)) + test_stdout_fd = open(filename_buf, O_WRONLY|O_CREAT|O_APPEND, S_IWUSR|S_IRUSR|S_IRGRP); + if (test_stdout_fd == -1) exit(errno); + if (dup2(test_stdout_fd, fileno(stdout)) == -1) + exit(errno); + strcpy(filename_buf, logdir); strcat(filename_buf, "/test-bin.stderr"); - if (!freopen(filename_buf, "a+", stderr)) + test_stderr_fd = open(filename_buf, O_WRONLY|O_CREAT|O_APPEND, S_IWUSR|S_IRUSR|S_IRGRP); + if (test_stderr_fd == -1) + exit(errno); + if (dup2(test_stderr_fd, fileno(stderr)) == -1) exit(errno); /* now start binary */ diff --git a/src/watchdog.c b/src/watchdog.c index 486384a..a69dba4 100644 --- a/src/watchdog.c +++ b/src/watchdog.c @@ -84,16 +84,25 @@ static int repair(char *rbinary, int result, char *name, int version) child_pid = fork(); if (!child_pid) { + int repair_stdout_fd, repair_stderr_fd; + /* Don't want the stdin and stdout of our repair program * to cause trouble. * So make stdout and stderr go to their respective files */ strcpy(filename_buf, logdir); strcat(filename_buf, "/repair-bin.stdout"); - if (!freopen(filename_buf, "a+", stdout)) + repair_stdout_fd = open(filename_buf, O_WRONLY|O_CREAT|O_APPEND, S_IWUSR|S_IRUSR|S_IRGRP); + if (repair_stdout_fd == -1) exit(errno); + if (dup2(repair_stdout_fd, fileno(stdout)) == -1) + exit(errno); + strcpy(filename_buf, logdir); strcat(filename_buf, "/repair-bin.stderr"); - if (!freopen(filename_buf, "a+", stderr)) + repair_stderr_fd = open(filename_buf, O_WRONLY|O_CREAT|O_APPEND, S_IWUSR|S_IRUSR|S_IRGRP); + if (repair_stderr_fd == -1) + exit(errno); + if (dup2(repair_stderr_fd, fileno(stderr)) == -1) exit(errno); /* now start binary */ -- 2.20.1