From: Tomer Cohen <[email protected]> Date: Sun, 16 Mar 2014 17:35:13 +0200
Added handling a non numeric input for a numeric field (of the opensm configuration file) and a range check for those parameters. Signed-off-by: Tomer Cohen <[email protected]> Signed-off-by: Hal Rosenstock <[email protected]> --- opensm/osm_subnet.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 68 insertions(+), 7 deletions(-) diff --git a/opensm/osm_subnet.c b/opensm/osm_subnet.c index aedfbd5..61e1fc2 100644 --- a/opensm/osm_subnet.c +++ b/opensm/osm_subnet.c @@ -275,12 +275,56 @@ static void opts_setup_sm_priority(osm_subn_t *p_subn, void *p_val) osm_set_sm_priority(p_sm, sm_priority); } +static int opts_strtoul(uint32_t *val, IN char *p_val_str, + IN char *p_key, uint32_t max_value) +{ + char *endptr; + unsigned long int tmp_val; + + tmp_val = strtoul(p_val_str, &endptr, 0); + *val = tmp_val; + if (*p_val_str == '\0' || *endptr != '\0') { + log_report("-E- Parsing error in field %s, expected " + "numeric input received: %s\n", p_key, p_val_str); + return -1; + } + if (tmp_val > max_value || + ((tmp_val == ULONG_MAX) && errno == ERANGE)) { + log_report("-E- Parsing error in field %s, value out of range\n", p_key); + return -1; + } + return 0; +} + +static int opts_strtoull(uint64_t *val, IN char *p_val_str, + IN char *p_key, uint64_t max_value) +{ + char *endptr; + unsigned long long int tmp_val; + + tmp_val = strtoull(p_val_str, &endptr, 0); + *val = tmp_val; + if (*p_val_str == '\0' || *endptr != '\0') { + log_report("-E- Parsing error in field %s, expected " + "numeric input received: %s\n", p_key, p_val_str); + return -1; + } + if (tmp_val > max_value || (tmp_val == ULLONG_MAX && errno == ERANGE)) { + log_report("-E- Parsing error in field %s, value out of range", p_key); + return -1; + } + return 0; +} + static void opts_parse_net64(IN osm_subn_t *p_subn, IN char *p_key, IN char *p_val_str, void *p_v1, void *p_v2, void (*pfn)(osm_subn_t *, void *)) { uint64_t *p_val1 = p_v1, *p_val2 = p_v2; - uint64_t val = strtoull(p_val_str, NULL, 0); + uint64_t val; + + if (opts_strtoull(&val, p_val_str, p_key, UINT64_MAX)) + return; if (cl_hton64(val) != *p_val1) { log_config_value(p_key, "0x%016" PRIx64, val); @@ -295,7 +339,10 @@ static void opts_parse_uint32(IN osm_subn_t *p_subn, IN char *p_key, void (*pfn)(osm_subn_t *, void *)) { uint32_t *p_val1 = p_v1, *p_val2 = p_v2; - uint32_t val = strtoul(p_val_str, NULL, 0); + uint32_t val; + + if (opts_strtoul(&val, p_val_str, p_key, UINT32_MAX)) + return; if (val != *p_val1) { log_config_value(p_key, "%u", val); @@ -310,7 +357,10 @@ static void opts_parse_net32(IN osm_subn_t *p_subn, IN char *p_key, void (*pfn)(osm_subn_t *, void *)) { uint32_t *p_val1 = p_v1, *p_val2 = p_v2; - uint32_t val = strtoul(p_val_str, NULL, 0); + uint32_t val; + + if (opts_strtoul(&val, p_val_str, p_key, UINT32_MAX)) + return; if (cl_hton32(val) != *p_val1) { log_config_value(p_key, "%u", val); @@ -320,7 +370,6 @@ static void opts_parse_net32(IN osm_subn_t *p_subn, IN char *p_key, } } - static void opts_parse_int32(IN osm_subn_t *p_subn, IN char *p_key, IN char *p_val_str, void *p_v1, void *p_v2, void (*pfn)(osm_subn_t *, void *)) @@ -341,8 +390,12 @@ static void opts_parse_uint16(IN osm_subn_t *p_subn, IN char *p_key, void (*pfn)(osm_subn_t *, void *)) { uint16_t *p_val1 = p_v1, *p_val2 = p_v2; - uint16_t val = (uint16_t) strtoul(p_val_str, NULL, 0); + uint32_t tmp_val; + + if (opts_strtoul(&tmp_val, p_val_str, p_key, UINT16_MAX)) + return; + uint16_t val = (uint16_t) tmp_val; if (val != *p_val1) { log_config_value(p_key, "%u", val); if (pfn) @@ -356,8 +409,12 @@ static void opts_parse_net16(IN osm_subn_t *p_subn, IN char *p_key, void (*pfn)(osm_subn_t *, void *)) { uint16_t *p_val1 = p_v1, *p_val2 = p_v2; - uint16_t val = strtoul(p_val_str, NULL, 0); + uint32_t tmp_val; + if (opts_strtoul(&tmp_val, p_val_str, p_key, UINT16_MAX)) + return; + + uint16_t val = (uint16_t) tmp_val; if (cl_hton16(val) != *p_val1) { log_config_value(p_key, "0x%04x", val); if (pfn) @@ -371,8 +428,12 @@ static void opts_parse_uint8(IN osm_subn_t *p_subn, IN char *p_key, void (*pfn)(osm_subn_t *, void *)) { uint8_t *p_val1 = p_v1, *p_val2 = p_v2; - uint8_t val = strtoul(p_val_str, NULL, 0); + uint32_t tmp_val; + + if (opts_strtoul(&tmp_val, p_val_str, p_key, UINT8_MAX)) + return; + uint8_t val = (uint8_t) tmp_val; if (val != *p_val1) { log_config_value(p_key, "%u", val); if (pfn) -- 1.7.8.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
