| 1 | From 01cd2d15a9bf1109e0e71b3e31b835d63dcf9cd8 Mon Sep 17 00:00:00 2001
|
| 2 | From: Maxime Devos <[email protected]>, Yin Kangkai <[email protected]>, Sudip Mukherjee <[email protected]>
|
| 3 | Subject: [PATCH]
|
| 4 |
|
| 5 | Fix segfault when run as normal user
|
| 6 |
|
| 7 | Also exit immediately when "restartd -h"
|
| 8 | Signed-off-by: Yin Kangkai <[email protected]>
|
| 9 |
|
| 10 | Fix build with gcc-10
|
| 11 |
|
| 12 | Bug: https://bugs.debian.org/957761
|
| 13 | Signed-off-by: Sudip Mukherjee <[email protected]>
|
| 14 |
|
| 15 | Handle memory allocation failures.
|
| 16 |
|
| 17 | This makes the code a little more robust.
|
| 18 | Signed-off-by: Maxime Devos <[email protected]>
|
| 19 |
|
| 20 | Handle fopen failures.
|
| 21 |
|
| 22 | This makes the code a little more robust. What if /var/run does not
|
| 23 | exist, or we do not have permission to open
|
| 24 | /var/run/restartd.pid (EPERM?) due to SELinux misconfiguration?
|
| 25 | Signed-off-by: Maxime Devos <[email protected]>
|
| 26 |
|
| 27 | Handle printf and fprintf failures.
|
| 28 |
|
| 29 | This makes the code a little more robust. What if the write was
|
| 30 | refused to the underlying device being removed?
|
| 31 |
|
| 32 | The --help, debug and stderr printfs were ignored because there error
|
| 33 | handling does not appear important to me.
|
| 34 | Signed-off-by: Maxime Devos <[email protected]>
|
| 35 |
|
| 36 | Handle fclose failures when writing.
|
| 37 |
|
| 38 | This makes the code a little more robust. What if a quotum is exceeded?
|
| 39 | Signed-off-by: Maxime Devos <[email protected]>
|
| 40 | ---
|
| 41 | config.c | 19 +++++++++----
|
| 42 | config.h | 14 ++++++----
|
| 43 | restartd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-------
|
| 44 | 3 files changed, 92 insertions(+), 21 deletions(-)
|
| 45 |
|
| 46 | diff --git a/config.c b/config.c
|
| 47 | index f307b8a..5cc0271 100644
|
| 48 | |
| 49 | |
| 50 | @@ -57,7 +57,11 @@ int read_config(void)
|
| 51 | config_process_number = 0;
|
| 52 |
|
| 53 | line1 = (char *) malloc(MAX_LINE_LENGTH);
|
| 54 | + if (!line1)
|
| 55 | + oom_failure();
|
| 56 | line2 = (char *) malloc(MAX_LINE_LENGTH);
|
| 57 | + if (!line2)
|
| 58 | + oom_failure();
|
| 59 |
|
| 60 | if ((config_fd = fopen(config_file, "rt")) == NULL) {
|
| 61 | fprintf(stderr, "Error at opening config file: %s\n", config_file);
|
| 62 | @@ -155,11 +159,16 @@ void dump_config(void) {
|
| 63 | int i;
|
| 64 |
|
| 65 | for(i=0; i<config_process_number; i++) {
|
| 66 | - printf("ID=%d\n name=%s\n regexp=%s\n running=%s\n not_running=%s\n", i,
|
| 67 | - config_process[i].name,
|
| 68 | - config_process[i].regexp,
|
| 69 | - config_process[i].running,
|
| 70 | - config_process[i].not_running);
|
| 71 | + if (printf("ID=%d\n name=%s\n regexp=%s\n running=%s\n not_running=%s\n", i,
|
| 72 | + config_process[i].name,
|
| 73 | + config_process[i].regexp,
|
| 74 | + config_process[i].running,
|
| 75 | + config_process[i].not_running) < 0) {
|
| 76 | + /* Maybe stdout points to a file and a file system quotum was exceeded? */
|
| 77 | + fprintf(stderr, "Failed to dump the configuration. Exiting.\n");
|
| 78 | + syslog(LOG_ERR, "Failed to dump the configuration. Exiting.");
|
| 79 | + exit(1);
|
| 80 | + }
|
| 81 | }
|
| 82 |
|
| 83 | }
|
| 84 | diff --git a/config.h b/config.h
|
| 85 | index fabaa2b..2ba1cbe 100644
|
| 86 | |
| 87 | |
| 88 | @@ -1,6 +1,7 @@
|
| 89 | /* restartd - Process checker and/or restarter daemon
|
| 90 | * Copyright (C) 2000-2002 Tibor Koleszar <[email protected]>
|
| 91 | * Copyright (C) 2006 Aurélien GÉRÔME <[email protected]>
|
| 92 | + * Copyright (C) 2022 Maxime Devos <[email protected]>
|
| 93 | *
|
| 94 | * This program is free software; you can redistribute it and/or
|
| 95 | * modify it under the terms of the GNU General Public License
|
| 96 | @@ -25,12 +26,12 @@
|
| 97 |
|
| 98 | #define DEFAULT_CONFIG "/etc/restartd.conf"
|
| 99 |
|
| 100 | -int debug;
|
| 101 | -int config_process_number;
|
| 102 | -int check_interval;
|
| 103 | -int foreground;
|
| 104 | -struct config_process_type *config_process;
|
| 105 | -char *config_file;
|
| 106 | +extern int debug;
|
| 107 | +extern int config_process_number;
|
| 108 | +extern int check_interval;
|
| 109 | +extern int foreground;
|
| 110 | +extern struct config_process_type *config_process;
|
| 111 | +extern char *config_file;
|
| 112 |
|
| 113 | typedef struct config_process_type {
|
| 114 | char name[64];
|
| 115 | @@ -43,5 +44,6 @@ typedef struct config_process_type {
|
| 116 |
|
| 117 | int read_config(/* char *config_file */);
|
| 118 | void dump_config(void);
|
| 119 | +void oom_failure(void);
|
| 120 |
|
| 121 | #endif /* RESTARTD_CONFIG_H */
|
| 122 | diff --git a/restartd.c b/restartd.c
|
| 123 | index 2aa720c..aa74334 100644
|
| 124 | |
| 125 | |
| 126 | @@ -1,6 +1,7 @@
|
| 127 | /* restartd - Process checker and/or restarter daemon
|
| 128 | * Copyright (C) 2000-2002 Tibor Koleszar <[email protected]>
|
| 129 | * Copyright (C) 2006 Aurélien GÉRÔME <[email protected]>
|
| 130 | + * Copyright (C) 2022 Maxime Devos <[email protected]>
|
| 131 | *
|
| 132 | * This program is free software; you can redistribute it and/or
|
| 133 | * modify it under the terms of the GNU General Public License
|
| 134 | @@ -35,6 +36,13 @@
|
| 135 |
|
| 136 | #include "config.h"
|
| 137 |
|
| 138 | +int debug;
|
| 139 | +int config_process_number;
|
| 140 | +int check_interval;
|
| 141 | +int foreground;
|
| 142 | +struct config_process_type *config_process;
|
| 143 | +char *config_file;
|
| 144 | +
|
| 145 | /* SIGTERM & SIGHUP handler */
|
| 146 | void got_signal(int sig)
|
| 147 | {
|
| 148 | @@ -52,6 +60,17 @@ void got_signal(int sig)
|
| 149 | }
|
| 150 | }
|
| 151 |
|
| 152 | +/* Ignoring out-of-memory failures is risky on systems without virtual memory
|
| 153 | + where additionally at address 0 there is actually something important
|
| 154 | + mapped. Additionally, while often on Linux the OOM killer will kill processes
|
| 155 | + where an OOM happens, this is not always the case and there exist other systems
|
| 156 | + without an OOM killer (e.g. the Hurd). */
|
| 157 | +void oom_failure()
|
| 158 | +{
|
| 159 | + syslog(LOG_ERR, "Failed to allocate memory. Exiting.");
|
| 160 | + exit(1);
|
| 161 | +}
|
| 162 | +
|
| 163 | int main(int argc, char *argv[])
|
| 164 | {
|
| 165 | DIR *procdir_id;
|
| 166 | @@ -75,15 +94,21 @@ int main(int argc, char *argv[])
|
| 167 |
|
| 168 | /* Options */
|
| 169 | config_file = strdup(DEFAULT_CONFIG);
|
| 170 | + if (!config_file)
|
| 171 | + oom_failure();
|
| 172 | +
|
| 173 | list_only = 0;
|
| 174 |
|
| 175 | for(i = 0; i < argc; i++) {
|
| 176 | if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) {
|
| 177 | config_file = strdup(argv[i + 1]);
|
| 178 | + if (!config_file)
|
| 179 | + oom_failure();
|
| 180 | }
|
| 181 | if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
|
| 182 | printf("restard %s - Copyright 2000-2002 Tibor Koleszar <[email protected]>\n"
|
| 183 | - " Copyright 2006 Aurélien GÉRÔME <[email protected]>\n",
|
| 184 | + " Copyright 2006 Aurélien GÉRÔME <[email protected]>\n"
|
| 185 | + " Copyright 2022 Maxime Devos <[email protected]>\n",
|
| 186 | VERSION);
|
| 187 | exit(0);
|
| 188 | }
|
| 189 | @@ -118,10 +143,13 @@ int main(int argc, char *argv[])
|
| 190 | " -i <interval_sec>: the check interval in second\n"
|
| 191 | " -l : list configuration options\n"
|
| 192 | " -h : help\n\n", VERSION);
|
| 193 | + exit(0);
|
| 194 | }
|
| 195 | }
|
| 196 |
|
| 197 | config_process = malloc(sizeof(struct config_process_type) * 128);
|
| 198 | + if (!config_process)
|
| 199 | + oom_failure();
|
| 200 |
|
| 201 | read_config();
|
| 202 | if (list_only) {
|
| 203 | @@ -133,9 +161,17 @@ int main(int argc, char *argv[])
|
| 204 | config_process_number);
|
| 205 |
|
| 206 | procdir_dirent = malloc(sizeof(struct dirent));
|
| 207 | + if (!procdir_dirent)
|
| 208 | + oom_failure();
|
| 209 | proc_cmdline_str = (char *) malloc(1024);
|
| 210 | + if (!proc_cmdline_str)
|
| 211 | + oom_failure();
|
| 212 | proc_cmdline_name = (char *) malloc(1024);
|
| 213 | + if (!proc_cmdline_name)
|
| 214 | + oom_failure();
|
| 215 | regc = malloc(1024);
|
| 216 | + if (!regc)
|
| 217 | + oom_failure();
|
| 218 |
|
| 219 | /* Catch signals */
|
| 220 | signal(SIGTERM, got_signal);
|
| 221 | @@ -187,8 +223,19 @@ int main(int argc, char *argv[])
|
| 222 | }
|
| 223 |
|
| 224 | out_proc = fopen("/var/run/restartd.pid", "wt");
|
| 225 | - fprintf(out_proc, "%d", getpid());
|
| 226 | - fclose(out_proc);
|
| 227 | + if (!out_proc) {
|
| 228 | + syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
|
| 229 | + return -1;
|
| 230 | + }
|
| 231 | + if (fprintf(out_proc, "%d", getpid()) < 0) {
|
| 232 | + syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
|
| 233 | + return -1;
|
| 234 | + }
|
| 235 | + if (fclose(out_proc) < 0) { /* errors can happen when flushing the buffer */
|
| 236 | + syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
|
| 237 | + return -1;
|
| 238 | + }
|
| 239 | +
|
| 240 |
|
| 241 | while(1) {
|
| 242 | if ((procdir_id = opendir("/proc")) == NULL) {
|
| 243 | @@ -237,16 +284,23 @@ int main(int argc, char *argv[])
|
| 244 | now = time(NULL);
|
| 245 |
|
| 246 | out_proc = fopen("/var/run/restartd", "wt");
|
| 247 | + if (!out_proc) {
|
| 248 | + syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
|
| 249 | + return -1;
|
| 250 | + }
|
| 251 |
|
| 252 | - fprintf(out_proc, "%s\n", ctime(&now));
|
| 253 | + if (fprintf(out_proc, "%s\n", ctime(&now)) < 0) {
|
| 254 | + syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
|
| 255 | + return -1;
|
| 256 | + }
|
| 257 |
|
| 258 | for(i=0; i<config_process_number; i++) {
|
| 259 | if (strlen(config_process[i].processes) > 0) {
|
| 260 | if (strlen(config_process[i].running) > 0) {
|
| 261 | strcpy(config_process[i].status, "running");
|
| 262 | - syslog(LOG_INFO, "%s is running, executing '%s'",
|
| 263 | + /* syslog(LOG_INFO, "%s is running, executing '%s'",
|
| 264 | config_process[i].name,
|
| 265 | - config_process[i].running);
|
| 266 | + config_process[i].running); */
|
| 267 | system(config_process[i].running);
|
| 268 | } else {
|
| 269 | strcpy(config_process[i].status, "running");
|
| 270 | @@ -267,12 +321,18 @@ int main(int argc, char *argv[])
|
| 271 | strcpy(config_process[i].status, "not running");
|
| 272 | }
|
| 273 |
|
| 274 | - fprintf(out_proc, "%-12s %-12s %s\n",
|
| 275 | - config_process[i].name, config_process[i].status,
|
| 276 | - config_process[i].processes);
|
| 277 | + if (fprintf(out_proc, "%-12s %-12s %s\n",
|
| 278 | + config_process[i].name, config_process[i].status,
|
| 279 | + config_process[i].processes) < 0) {
|
| 280 | + syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
|
| 281 | + return -1;
|
| 282 | + }
|
| 283 | }
|
| 284 |
|
| 285 | - fclose(out_proc);
|
| 286 | + if (fclose(out_proc) < 0) {
|
| 287 | + syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
|
| 288 | + return -1;
|
| 289 | + }
|
| 290 |
|
| 291 | sleep(check_interval);
|
| 292 | }
|
| 293 | --
|
| 294 | 2.37.3
|
| 295 |
|