diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2013-08-27 14:37:13 +0200 |
---|---|---|
committer | Holger Weiss <holger@zedat.fu-berlin.de> | 2013-08-27 14:37:13 +0200 |
commit | e9ede0f8e3b5a5402722ae8d10862f29d30c73ae (patch) | |
tree | a76d036ad6fd103941ffd6cb387bc0e7301ba588 | |
parent | 69b13552864cb6df639cceb94b8d09b1f9af8f17 (diff) | |
parent | a20611d4357c3c3ebe0a62776a1642e7904c1410 (diff) | |
download | monitoring-plugins-e9ede0f8e3b5a5402722ae8d10862f29d30c73ae.tar.gz |
Merge branch 'master' of https://github.com/ozamosi/nagios-plugins
* 'master' of https://github.com/ozamosi/nagios-plugins:
check_snmp: Close potential for using uninitialized memory
check_snmp: Dynamically grow all data structures
Conflicts:
plugins/check_snmp.c
-rw-r--r-- | plugins/check_snmp.c | 82 | ||||
-rw-r--r-- | plugins/common.h | 6 |
2 files changed, 64 insertions, 24 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index d2f2f8b5..9ca845d7 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c @@ -57,7 +57,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #define WARN_STRING 16 #define WARN_REGEX 32 -#define MAX_OIDS 8 +#define OID_COUNT_STEP 8 /* Longopts only arguments */ #define L_CALCULATE_RATE CHAR_MAX+1 @@ -112,6 +112,7 @@ char *privproto = NULL; char *authpasswd = NULL; char *privpasswd = NULL; char **oids = NULL; +size_t oids_size = NULL; char *label; char *units; char *port; @@ -121,19 +122,22 @@ int invert_search=0; char **labels = NULL; char **unitv = NULL; size_t nlabels = 0; -size_t labels_size = 8; +size_t labels_size = OID_COUNT_STEP; size_t nunits = 0; -size_t unitv_size = 8; +size_t unitv_size = OID_COUNT_STEP; int numoids = 0; int numauthpriv = 0; int verbose = 0; int usesnmpgetnext = FALSE; char *warning_thresholds = NULL; char *critical_thresholds = NULL; -thresholds *thlds[MAX_OIDS]; -double response_value[MAX_OIDS]; +thresholds **thlds; +size_t thlds_size = OID_COUNT_STEP; +double *response_value; +size_t response_size = OID_COUNT_STEP; int retries = 0; -int eval_method[MAX_OIDS]; +int *eval_method; +size_t eval_size = OID_COUNT_STEP; char *delimiter; char *output_delim; char *miblist = NULL; @@ -142,7 +146,8 @@ int calculate_rate = 0; double offset = 0.0; int rate_multiplier = 1; state_data *previous_state; -double previous_value[MAX_OIDS]; +double *previous_value; +size_t previous_size = OID_COUNT_STEP; int perf_labels = 1; @@ -206,8 +211,11 @@ main (int argc, char **argv) labels = malloc (labels_size * sizeof(*labels)); unitv = malloc (unitv_size * sizeof(*unitv)); - for (i = 0; i < MAX_OIDS; i++) - eval_method[i] = CHECK_UNDEF; + thlds = malloc (thlds_size * sizeof(*thlds)); + response_value = malloc (response_size * sizeof(*response_value)); + previous_value = malloc (previous_size * sizeof(*previous_value)); + eval_method = calloc (eval_size, sizeof(*eval_method)); + oids = calloc(oids_size, sizeof (char *)); label = strdup ("SNMP"); units = strdup (""); @@ -225,13 +233,14 @@ main (int argc, char **argv) np_set_args(argc, argv); + time(¤t_time); + if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); if(calculate_rate) { if (!strcmp(label, "SNMP")) label = strdup("SNMP RATE"); - time(¤t_time); i=0; previous_state = np_state_read(); if(previous_state!=NULL) { @@ -240,6 +249,10 @@ main (int argc, char **argv) while((ap = strsep(&previous_string, ":")) != NULL) { if(verbose>2) printf("State for %d=%s\n", i, ap); + while (i >= previous_size) { + previous_size += OID_COUNT_STEP; + previous_value = realloc(previous_value, previous_size * sizeof(*previous_value)); + } previous_value[i++]=strtod(ap,NULL); } } @@ -255,6 +268,11 @@ main (int argc, char **argv) w = w ? fix_snmp_range(w) : NULL; c = c ? fix_snmp_range(c) : NULL; + while (i >= thlds_size) { + thlds_size += OID_COUNT_STEP; + thlds = realloc(thlds, thlds_size * sizeof(*thlds)); + } + /* Skip empty thresholds, while avoiding segfault */ set_thresholds(&thlds[i], w ? strpbrk(w, NP_THRESHOLDS_CHARS) : NULL, @@ -434,6 +452,10 @@ main (int argc, char **argv) ptr = strpbrk (show, "0123456789"); if (ptr == NULL) die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show); + while (i >= response_size) { + response_size += OID_COUNT_STEP; + response_value = realloc(response_value, response_size * sizeof(*response_value)); + } response_value[i] = strtod (ptr, NULL) + offset; if(calculate_rate) { @@ -461,7 +483,7 @@ main (int argc, char **argv) } /* Process this block for string matching */ - else if (eval_method[i] & CRIT_STRING) { + else if (eval_size > i && eval_method[i] & CRIT_STRING) { if (strcmp (show, string_value)) iresult = (invert_search==0) ? STATE_CRITICAL : STATE_OK; else @@ -469,7 +491,7 @@ main (int argc, char **argv) } /* Process this block for regex matching */ - else if (eval_method[i] & CRIT_REGEX) { + else if (eval_size > i && eval_method[i] & CRIT_REGEX) { excode = regexec (&preg, response, 10, pmatch, eflags); if (excode == 0) { iresult = (invert_search==0) ? STATE_OK : STATE_CRITICAL; @@ -487,9 +509,9 @@ main (int argc, char **argv) /* Process this block for existence-nonexistence checks */ /* TV: Should this be outside of this else block? */ else { - if (eval_method[i] & CRIT_PRESENT) + if (eval_size > i && eval_method[i] & CRIT_PRESENT) iresult = STATE_CRITICAL; - else if (eval_method[i] & WARN_PRESENT) + else if (eval_size > i && eval_method[i] & WARN_PRESENT) iresult = STATE_WARNING; else if (response && iresult == STATE_DEPENDENT) iresult = STATE_OK; @@ -729,23 +751,36 @@ process_arguments (int argc, char **argv) */ needmibs = TRUE; } - if (!oids) oids = calloc(MAX_OIDS, sizeof (char *)); - for (ptr = strtok(optarg, ", "); ptr != NULL && j < MAX_OIDS; ptr = strtok(NULL, ", "), j++) { + for (ptr = strtok(optarg, ", "); ptr != NULL; ptr = strtok(NULL, ", "), j++) { + while (j >= oids_size) { + oids_size += OID_COUNT_STEP; + oids = realloc(oids, oids_size * sizeof (*oids)); + } oids[j] = strdup(ptr); } numoids = j; if (c == 'E' || c == 'e') { jj++; ii++; + while (j+1 >= eval_size) { + eval_size += OID_COUNT_STEP; + eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); + memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); + } + if (c == 'E') + eval_method[j+1] |= WARN_PRESENT; + else if (c == 'e') + eval_method[j+1] |= CRIT_PRESENT; } - if (c == 'E') - eval_method[j+1] |= WARN_PRESENT; - else if (c == 'e') - eval_method[j+1] |= CRIT_PRESENT; break; case 's': /* string or substring */ strncpy (string_value, optarg, sizeof (string_value) - 1); string_value[sizeof (string_value) - 1] = 0; + while (jj >= eval_size) { + eval_size += OID_COUNT_STEP; + eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); + memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); + } eval_method[jj++] = CRIT_STRING; ii++; break; @@ -761,6 +796,11 @@ process_arguments (int argc, char **argv) printf (_("Could Not Compile Regular Expression")); return ERROR; } + while (jj >= eval_size) { + eval_size += OID_COUNT_STEP; + eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); + memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); + } eval_method[jj++] = CRIT_REGEX; ii++; break; @@ -1127,7 +1167,7 @@ print_help (void) printf ("\n"); printf ("%s\n", _("Notes:")); printf (" %s\n", _("- Multiple OIDs (and labels) may be indicated by a comma or space-delimited ")); - printf (" %s %i %s\n", _("list (lists with internal spaces must be quoted). Maximum:"), MAX_OIDS, _("OIDs.")); + printf (" %s %i %s\n", _("list (lists with internal spaces must be quoted).")); printf(" -%s", UT_THRESHOLDS_NOTES); diff --git a/plugins/common.h b/plugins/common.h index f1358380..b49ad945 100644 --- a/plugins/common.h +++ b/plugins/common.h @@ -208,9 +208,9 @@ enum { # define bindtextdomain(Domainname, Dirname) /* empty */ #endif -/* For non-GNU compilers to ignore __attribute__ */ -#ifndef __GNUC__ -# define __attribute__(x) /* do nothing */ +/* For non-GNU/non-clang compilers to ignore __attribute__ */ +#if !defined(__GNUC__) && !defined(__CLANG__) +# define __attribute__(noreturn) /* do nothing */ #endif #endif /* _COMMON_H_ */ |