diff options
author | Sven Nierlein <sven@nierlein.de> | 2019-04-25 13:03:10 +0200 |
---|---|---|
committer | Sven Nierlein <sven@nierlein.org> | 2019-05-24 14:51:10 +0200 |
commit | e8325b39c47e6fbf7c8c1e31f9026870d9520af5 (patch) | |
tree | 1c55421a51808253cbe59348e45bd0cb580354c5 | |
parent | 4131f2f268e7d771490ebeadbae50b4f95d69695 (diff) | |
download | monitoring-plugins-e8325b39c47e6fbf7c8c1e31f9026870d9520af5.tar.gz |
fix maxfd being zero
If _SC_OPEN_MAX is available then maxfd was zero initialized and never set to the value from sysconf.
This leads to segfaults with free(): invalid size introduced by commit 7cafb0e84550035fe671662c293122be975065ca.
Signed-off-by: Sven Nierlein <sven@nierlein.de>
-rw-r--r-- | plugins/popen.c | 52 | ||||
-rw-r--r-- | plugins/runcmd.c | 10 | ||||
-rw-r--r-- | plugins/utils.c | 16 | ||||
-rw-r--r-- | plugins/utils.h | 2 |
4 files changed, 23 insertions, 57 deletions
diff --git a/plugins/popen.c b/plugins/popen.c index 116d168d..557fb44e 100644 --- a/plugins/popen.c +++ b/plugins/popen.c | |||
@@ -78,14 +78,9 @@ RETSIGTYPE popen_timeout_alarm_handler (int); | |||
78 | 78 | ||
79 | #define min(a,b) ((a) < (b) ? (a) : (b)) | 79 | #define min(a,b) ((a) < (b) ? (a) : (b)) |
80 | #define max(a,b) ((a) > (b) ? (a) : (b)) | 80 | #define max(a,b) ((a) > (b) ? (a) : (b)) |
81 | static void err_sys (const char *, ...) __attribute__((noreturn,format(printf, 1, 2))); | ||
82 | char *rtrim (char *, const char *); | ||
83 | 81 | ||
84 | char *pname = NULL; /* caller can set this from argv[0] */ | 82 | char *pname = NULL; /* caller can set this from argv[0] */ |
85 | 83 | ||
86 | /*int *childerr = NULL;*//* ptr to array allocated at run-time */ | ||
87 | /*extern pid_t *childpid = NULL; *//* ptr to array allocated at run-time */ | ||
88 | |||
89 | #ifdef REDHAT_SPOPEN_ERROR | 84 | #ifdef REDHAT_SPOPEN_ERROR |
90 | static volatile int childtermd = 0; | 85 | static volatile int childtermd = 0; |
91 | #endif | 86 | #endif |
@@ -184,6 +179,9 @@ spopen (const char *cmdstring) | |||
184 | } | 179 | } |
185 | argv[i] = NULL; | 180 | argv[i] = NULL; |
186 | 181 | ||
182 | if(maxfd == 0) | ||
183 | maxfd = open_max(); | ||
184 | |||
187 | if (childpid == NULL) { /* first time through */ | 185 | if (childpid == NULL) { /* first time through */ |
188 | if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL) | 186 | if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL) |
189 | return (NULL); | 187 | return (NULL); |
@@ -296,47 +294,3 @@ popen_timeout_alarm_handler (int signo) | |||
296 | exit (STATE_CRITICAL); | 294 | exit (STATE_CRITICAL); |
297 | } | 295 | } |
298 | } | 296 | } |
299 | |||
300 | |||
301 | /* Fatal error related to a system call. | ||
302 | * Print a message and die. */ | ||
303 | |||
304 | #define MAXLINE 2048 | ||
305 | static void | ||
306 | err_sys (const char *fmt, ...) | ||
307 | { | ||
308 | int errnoflag = 1; | ||
309 | int errno_save; | ||
310 | char buf[MAXLINE]; | ||
311 | |||
312 | va_list ap; | ||
313 | |||
314 | va_start (ap, fmt); | ||
315 | /* err_doit (1, fmt, ap); */ | ||
316 | errno_save = errno; /* value caller might want printed */ | ||
317 | vsprintf (buf, fmt, ap); | ||
318 | if (errnoflag) | ||
319 | sprintf (buf + strlen (buf), ": %s", strerror (errno_save)); | ||
320 | strcat (buf, "\n"); | ||
321 | fflush (stdout); /* in case stdout and stderr are the same */ | ||
322 | fputs (buf, stderr); | ||
323 | fflush (NULL); /* flushes all stdio output streams */ | ||
324 | va_end (ap); | ||
325 | exit (1); | ||
326 | } | ||
327 | |||
328 | char * | ||
329 | rtrim (char *str, const char *tok) | ||
330 | { | ||
331 | int i = 0; | ||
332 | int j = sizeof (str); | ||
333 | |||
334 | while (str != NULL && i < j) { | ||
335 | if (*(str + i) == *tok) { | ||
336 | sprintf (str + i, "%s", "\0"); | ||
337 | return str; | ||
338 | } | ||
339 | i++; | ||
340 | } | ||
341 | return str; | ||
342 | } | ||
diff --git a/plugins/runcmd.c b/plugins/runcmd.c index c3828678..a7155d27 100644 --- a/plugins/runcmd.c +++ b/plugins/runcmd.c | |||
@@ -86,14 +86,8 @@ extern void die (int, const char *, ...) | |||
86 | * through this api and thus achieve async-safeness throughout the api */ | 86 | * through this api and thus achieve async-safeness throughout the api */ |
87 | void np_runcmd_init(void) | 87 | void np_runcmd_init(void) |
88 | { | 88 | { |
89 | #ifndef maxfd | 89 | if(maxfd == 0) |
90 | if(!maxfd && (maxfd = sysconf(_SC_OPEN_MAX)) < 0) { | 90 | maxfd = open_max(); |
91 | /* possibly log or emit a warning here, since there's no | ||
92 | * guarantee that our guess at maxfd will be adequate */ | ||
93 | maxfd = 256; | ||
94 | } | ||
95 | #endif | ||
96 | |||
97 | if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t)); | 91 | if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t)); |
98 | } | 92 | } |
99 | 93 | ||
diff --git a/plugins/utils.c b/plugins/utils.c index ee620133..348ec022 100644 --- a/plugins/utils.c +++ b/plugins/utils.c | |||
@@ -678,3 +678,19 @@ char *sperfdata_int (const char *label, | |||
678 | 678 | ||
679 | return data; | 679 | return data; |
680 | } | 680 | } |
681 | |||
682 | int | ||
683 | open_max (void) | ||
684 | { | ||
685 | errno = 0; | ||
686 | if (maxfd > 0) | ||
687 | return(maxfd); | ||
688 | |||
689 | if ((maxfd = sysconf (_SC_OPEN_MAX)) < 0) { | ||
690 | if (errno == 0) | ||
691 | maxfd = DEFAULT_MAXFD; /* it's indeterminate */ | ||
692 | else | ||
693 | die (STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n")); | ||
694 | } | ||
695 | return(maxfd); | ||
696 | } | ||
diff --git a/plugins/utils.h b/plugins/utils.h index 6aa316fe..33a20547 100644 --- a/plugins/utils.h +++ b/plugins/utils.h | |||
@@ -97,6 +97,8 @@ char *sperfdata (const char *, double, const char *, char *, char *, | |||
97 | char *sperfdata_int (const char *, int, const char *, char *, char *, | 97 | char *sperfdata_int (const char *, int, const char *, char *, char *, |
98 | int, int, int, int); | 98 | int, int, int, int); |
99 | 99 | ||
100 | int open_max (void); | ||
101 | |||
100 | /* The idea here is that, although not every plugin will use all of these, | 102 | /* The idea here is that, although not every plugin will use all of these, |
101 | most will or should. Therefore, for consistency, these very common | 103 | most will or should. Therefore, for consistency, these very common |
102 | options should have only these meanings throughout the overall suite */ | 104 | options should have only these meanings throughout the overall suite */ |