watchdog/0009-Bugfix-against-watchdo...

102 lines
3.5 KiB
Diff

From 7310afccc11070fd4207a41881401d619dd113b1 Mon Sep 17 00:00:00 2001
From: Paul Crawford <psc@sat.dundee.ac.uk>
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 <errno.h>
+#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
@@ -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