From 7cafb0e84550035fe671662c293122be975065ca Mon Sep 17 00:00:00 2001 From: Sven Nierlein Date: Fri, 15 Feb 2019 10:36:28 +0100 Subject: check_by_ssh: fix child process leak on timeouts When check_by_ssh runs into a timeout it simply exits keeping all child processes running. Simply adopting the kill loop from runcmd_timeout_alarm_handler() fixes this. Signed-off-by: Sven Nierlein --- plugins/utils.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'plugins/utils.h') diff --git a/plugins/utils.h b/plugins/utils.h index a436e1ca..6aa316fe 100644 --- a/plugins/utils.h +++ b/plugins/utils.h @@ -29,13 +29,6 @@ suite of plugins. */ void support (void); void print_revision (const char *, const char *); -/* Handle timeouts */ - -extern unsigned int timeout_state; -extern unsigned int timeout_interval; - -RETSIGTYPE timeout_alarm_handler (int); - extern time_t start_time, end_time; /* Test input types */ @@ -89,8 +82,6 @@ void usage4(const char *) __attribute__((noreturn)); void usage5(void) __attribute__((noreturn)); void usage_va(const char *fmt, ...) __attribute__((noreturn)); -const char *state_text (int); - #define max(a,b) (((a)>(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b)) -- cgit v1.2.3-74-g34f1 From e8325b39c47e6fbf7c8c1e31f9026870d9520af5 Mon Sep 17 00:00:00 2001 From: Sven Nierlein Date: Thu, 25 Apr 2019 13:03:10 +0200 Subject: 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 --- plugins/popen.c | 52 +++------------------------------------------------- plugins/runcmd.c | 10 ++-------- plugins/utils.c | 16 ++++++++++++++++ plugins/utils.h | 2 ++ 4 files changed, 23 insertions(+), 57 deletions(-) (limited to 'plugins/utils.h') 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); #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) > (b) ? (a) : (b)) -static void err_sys (const char *, ...) __attribute__((noreturn,format(printf, 1, 2))); -char *rtrim (char *, const char *); char *pname = NULL; /* caller can set this from argv[0] */ -/*int *childerr = NULL;*//* ptr to array allocated at run-time */ -/*extern pid_t *childpid = NULL; *//* ptr to array allocated at run-time */ - #ifdef REDHAT_SPOPEN_ERROR static volatile int childtermd = 0; #endif @@ -184,6 +179,9 @@ spopen (const char *cmdstring) } argv[i] = NULL; + if(maxfd == 0) + maxfd = open_max(); + if (childpid == NULL) { /* first time through */ if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL) return (NULL); @@ -296,47 +294,3 @@ popen_timeout_alarm_handler (int signo) exit (STATE_CRITICAL); } } - - -/* Fatal error related to a system call. - * Print a message and die. */ - -#define MAXLINE 2048 -static void -err_sys (const char *fmt, ...) -{ - int errnoflag = 1; - int errno_save; - char buf[MAXLINE]; - - va_list ap; - - va_start (ap, fmt); - /* err_doit (1, fmt, ap); */ - errno_save = errno; /* value caller might want printed */ - vsprintf (buf, fmt, ap); - if (errnoflag) - sprintf (buf + strlen (buf), ": %s", strerror (errno_save)); - strcat (buf, "\n"); - fflush (stdout); /* in case stdout and stderr are the same */ - fputs (buf, stderr); - fflush (NULL); /* flushes all stdio output streams */ - va_end (ap); - exit (1); -} - -char * -rtrim (char *str, const char *tok) -{ - int i = 0; - int j = sizeof (str); - - while (str != NULL && i < j) { - if (*(str + i) == *tok) { - sprintf (str + i, "%s", "\0"); - return str; - } - i++; - } - return str; -} 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 *, ...) * through this api and thus achieve async-safeness throughout the api */ void np_runcmd_init(void) { -#ifndef maxfd - if(!maxfd && (maxfd = sysconf(_SC_OPEN_MAX)) < 0) { - /* possibly log or emit a warning here, since there's no - * guarantee that our guess at maxfd will be adequate */ - maxfd = 256; - } -#endif - + if(maxfd == 0) + maxfd = open_max(); if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t)); } 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, return data; } + +int +open_max (void) +{ + errno = 0; + if (maxfd > 0) + return(maxfd); + + if ((maxfd = sysconf (_SC_OPEN_MAX)) < 0) { + if (errno == 0) + maxfd = DEFAULT_MAXFD; /* it's indeterminate */ + else + die (STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n")); + } + return(maxfd); +} 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 *, char *sperfdata_int (const char *, int, const char *, char *, char *, int, int, int, int); +int open_max (void); + /* The idea here is that, although not every plugin will use all of these, most will or should. Therefore, for consistency, these very common options should have only these meanings throughout the overall suite */ -- cgit v1.2.3-74-g34f1 From 66e245375992c3942dbd5761f8b991e52bf5f9ab Mon Sep 17 00:00:00 2001 From: rincewind Date: Sat, 25 Sep 2021 23:24:34 +0200 Subject: Introduce new perfdata functions and stuff for using (u)int64_t --- plugins/utils.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/utils.h | 10 +++++ 2 files changed, 130 insertions(+) (limited to 'plugins/utils.h') diff --git a/plugins/utils.c b/plugins/utils.c index 348ec022..011f715d 100644 --- a/plugins/utils.c +++ b/plugins/utils.c @@ -27,6 +27,8 @@ #include "utils_base.h" #include #include +#include +#include #include @@ -239,6 +241,46 @@ is_intnonneg (char *number) return FALSE; } +/* + * Checks whether the number in the string _number_ can be put inside a int64_t + * On success the number will be written to the _target_ address, if _target_ is not set + * to NULL. + */ +bool is_int64(char *number, int64_t *target) { + errno = 0; + uint64_t tmp = strtoll(number, NULL, 10); + if (errno != 0) { + return false; + } + if (tmp < INT64_MIN || tmp > INT64_MAX) { + return false; + } + if (target != NULL) { + *target = tmp; + } + return true; +} + +/* + * Checks whether the number in the string _number_ can be put inside a uint64_t + * On success the number will be written to the _target_ address, if _target_ is not set + * to NULL. + */ +bool is_uint64(char *number, uint64_t *target) { + errno = 0; + uint64_t tmp = strtoll(number, NULL, 10); + if (errno != 0) { + return false; + } + if (tmp < 0 || tmp > UINT64_MAX) { + return false; + } + if (target != NULL) { + *target = tmp; + } + return true; +} + int is_intpercent (char *number) { @@ -556,6 +598,84 @@ char *perfdata (const char *label, } +char *perfdata_uint64 (const char *label, + uint64_t val, + const char *uom, + int warnp, + uint64_t warn, + int critp, + uint64_t crit, + int minp, + uint64_t minv, + int maxp, + uint64_t maxv) +{ + char *data = NULL; + + if (strpbrk (label, "'= ")) + xasprintf (&data, "'%s'=%ld%s;", label, val, uom); + else + xasprintf (&data, "%s=%ld%s;", label, val, uom); + + if (warnp) + xasprintf (&data, "%s%ld;", data, warn); + else + xasprintf (&data, "%s;", data); + + if (critp) + xasprintf (&data, "%s%ld;", data, crit); + else + xasprintf (&data, "%s;", data); + + if (minp) + xasprintf (&data, "%s%ld", data, minv); + + if (maxp) + xasprintf (&data, "%s;%ld", data, maxv); + + return data; +} + + +char *perfdata_int64 (const char *label, + int64_t val, + const char *uom, + int warnp, + int64_t warn, + int critp, + int64_t crit, + int minp, + int64_t minv, + int maxp, + int64_t maxv) +{ + char *data = NULL; + + if (strpbrk (label, "'= ")) + xasprintf (&data, "'%s'=%ld%s;", label, val, uom); + else + xasprintf (&data, "%s=%ld%s;", label, val, uom); + + if (warnp) + xasprintf (&data, "%s%ld;", data, warn); + else + xasprintf (&data, "%s;", data); + + if (critp) + xasprintf (&data, "%s%ld;", data, crit); + else + xasprintf (&data, "%s;", data); + + if (minp) + xasprintf (&data, "%s%ld", data, minv); + + if (maxp) + xasprintf (&data, "%s;%ld", data, maxv); + + return data; +} + + char *fperfdata (const char *label, double val, const char *uom, diff --git a/plugins/utils.h b/plugins/utils.h index 33a20547..91a9c3f9 100644 --- a/plugins/utils.h +++ b/plugins/utils.h @@ -16,6 +16,9 @@ suite of plugins. */ /* now some functions etc are being defined in ../lib/utils_base.c */ #include "utils_base.h" + +#include + #ifdef NP_EXTRA_OPTS /* Include extra-opts functions if compiled in */ #include "extra_opts.h" @@ -38,6 +41,7 @@ int is_intpos (char *); int is_intneg (char *); int is_intnonneg (char *); int is_intpercent (char *); +bool is_uint64(char *number, uint64_t *target); int is_numeric (char *); int is_positive (char *); @@ -88,6 +92,12 @@ void usage_va(const char *fmt, ...) __attribute__((noreturn)); char *perfdata (const char *, long int, const char *, int, long int, int, long int, int, long int, int, long int); +char *perfdata_uint64 (const char *, uint64_t , const char *, int, uint64_t, + int, uint64_t, int, uint64_t, int, uint64_t); + +char *perfdata_int64 (const char *, int64_t, const char *, int, int64_t, + int, int64_t, int, int64_t, int, int64_t); + char *fperfdata (const char *, double, const char *, int, double, int, double, int, double, int, double); -- cgit v1.2.3-74-g34f1 From 46c5327e348540ab04dc37d42f6d1c5408179fa6 Mon Sep 17 00:00:00 2001 From: RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 2 Oct 2021 23:37:12 +0200 Subject: Revert to poor man's logic --- plugins/check_swap.c | 13 ++++++------- plugins/utils.c | 16 ++++++++-------- plugins/utils.h | 5 ++--- 3 files changed, 16 insertions(+), 18 deletions(-) (limited to 'plugins/utils.h') diff --git a/plugins/check_swap.c b/plugins/check_swap.c index 4d124a35..685c2cc5 100644 --- a/plugins/check_swap.c +++ b/plugins/check_swap.c @@ -37,7 +37,6 @@ const char *email = "devel@monitoring-plugins.org"; #include #include #include -#include #ifdef HAVE_DECL_SWAPCTL # ifdef HAVE_SYS_PARAM_H @@ -56,7 +55,7 @@ const char *email = "devel@monitoring-plugins.org"; #endif typedef struct { - bool is_percentage; + int is_percentage; uint64_t value; } threshold_t; @@ -69,7 +68,7 @@ void print_help (void); threshold_t warn; threshold_t crit; int verbose; -bool allswaps; +int allswaps; int no_swap_state = STATE_CRITICAL; int @@ -467,7 +466,7 @@ process_arguments (int argc, char **argv) if (optarg[length - 1] == '%') { /* It's percentage */ - warn.is_percentage = true; + warn.is_percentage = 1; optarg[length - 1] = '\0'; if (is_uint64(optarg, &warn.value)) { if (warn.value > 100) { @@ -478,7 +477,7 @@ process_arguments (int argc, char **argv) } } else { /* It's Bytes */ - warn.is_percentage = false; + warn.is_percentage = 0; if (is_uint64(optarg, &warn.value)) { break; } else { @@ -498,7 +497,7 @@ process_arguments (int argc, char **argv) if (optarg[length - 1] == '%') { /* It's percentage */ - crit.is_percentage = true; + crit.is_percentage = 1; optarg[length - 1] = '\0'; if (is_uint64(optarg, &crit.value)) { if (crit.value> 100) { @@ -509,7 +508,7 @@ process_arguments (int argc, char **argv) } } else { /* It's Bytes */ - crit.is_percentage = false; + crit.is_percentage = 0; if (is_uint64(optarg, &crit.value)) { break; } else { diff --git a/plugins/utils.c b/plugins/utils.c index 011f715d..f7f8952f 100644 --- a/plugins/utils.c +++ b/plugins/utils.c @@ -246,19 +246,19 @@ is_intnonneg (char *number) * On success the number will be written to the _target_ address, if _target_ is not set * to NULL. */ -bool is_int64(char *number, int64_t *target) { +int is_int64(char *number, int64_t *target) { errno = 0; uint64_t tmp = strtoll(number, NULL, 10); if (errno != 0) { - return false; + return 0; } if (tmp < INT64_MIN || tmp > INT64_MAX) { - return false; + return 0; } if (target != NULL) { *target = tmp; } - return true; + return 1; } /* @@ -266,19 +266,19 @@ bool is_int64(char *number, int64_t *target) { * On success the number will be written to the _target_ address, if _target_ is not set * to NULL. */ -bool is_uint64(char *number, uint64_t *target) { +int is_uint64(char *number, uint64_t *target) { errno = 0; uint64_t tmp = strtoll(number, NULL, 10); if (errno != 0) { - return false; + return 0; } if (tmp < 0 || tmp > UINT64_MAX) { - return false; + return 0; } if (target != NULL) { *target = tmp; } - return true; + return 1; } int diff --git a/plugins/utils.h b/plugins/utils.h index 91a9c3f9..5b54da3c 100644 --- a/plugins/utils.h +++ b/plugins/utils.h @@ -17,8 +17,6 @@ suite of plugins. */ #include "utils_base.h" -#include - #ifdef NP_EXTRA_OPTS /* Include extra-opts functions if compiled in */ #include "extra_opts.h" @@ -41,7 +39,8 @@ int is_intpos (char *); int is_intneg (char *); int is_intnonneg (char *); int is_intpercent (char *); -bool is_uint64(char *number, uint64_t *target); +int is_uint64(char *number, uint64_t *target); +int is_int64(char *number, int64_t *target); int is_numeric (char *); int is_positive (char *); -- cgit v1.2.3-74-g34f1