From: Swen Schillig Date: Mon, 28 Jan 2019 12:36:45 +0000 (+0100) Subject: utils: Use wrapper for string to integer conversion X-Git-Tag: talloc-2.2.0~235 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e82228f2e09d66807d0bce150bb1db9731bbd4d4;p=thirdparty%2Fsamba.git utils: Use wrapper for string to integer conversion In order to detect an value overflow error during the string to integer conversion with strtoul/strtoull, the errno variable must be set to zero before the execution and checked after the conversion is performed. This is achieved by using the wrapper function strtoul_err and strtoull_err. Signed-off-by: Swen Schillig Reviewed-by: Ralph Böhme Reviewed-by: Jeremy Allison --- diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index b49d5f43381..f6c9f3a1a3d 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -628,8 +628,9 @@ static bool parse_uint32(const char *str, uint32_t *result) { unsigned long val; char *endptr; + int error = 0; - val = strtoul(str, &endptr, 10); + val = strtoul_err(str, &endptr, 10, &error); if (str == endptr) { return false; @@ -637,11 +638,7 @@ static bool parse_uint32(const char *str, uint32_t *result) if (*endptr != '\0') { return false; } - if ((val == ULONG_MAX) && (errno == ERANGE)) { - return false; - } - if ((val & UINT32_MAX) != val) { - /* overflow */ + if (error != 0) { return false; } *result = val; /* Potential crop */ diff --git a/source3/utils/net_registry.c b/source3/utils/net_registry.c index 01a36b20e7c..74224ddbf15 100644 --- a/source3/utils/net_registry.c +++ b/source3/utils/net_registry.c @@ -509,7 +509,14 @@ static int net_registry_setvalue(struct net_context *c, int argc, } if (strequal(argv[2], "dword")) { - uint32_t v = strtoul(argv[3], NULL, 10); + int error = 0; + uint32_t v; + + v = strtoul_err(argv[3], NULL, 10, &error); + if (error != 0) { + goto done; + } + value.type = REG_DWORD; value.data = data_blob_talloc(ctx, NULL, 4); SIVAL(value.data.data, 0, v); @@ -641,7 +648,12 @@ static int net_registry_increment(struct net_context *c, int argc, state.increment = 1; if (argc == 3) { - state.increment = strtoul(argv[2], NULL, 10); + int error = 0; + + state.increment = strtoul_err(argv[2], NULL, 10, &error); + if (error != 0) { + goto done; + } } status = g_lock_do(string_term_tdb_data("registry_increment_lock"), diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index 19b73fd7042..84936ee31ae 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -603,7 +603,14 @@ static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c, } if (strequal(argv[2], "dword")) { - uint32_t v = strtoul(argv[3], NULL, 10); + int error = 0; + uint32_t v; + + v = strtoul_err(argv[3], NULL, 10, &error); + if (error != 0) { + goto error; + } + value.type = REG_DWORD; value.data = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(value.data.data, 0, v); diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index 5a9d1792d51..fc2a7baacef 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -484,6 +484,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv uint32_t old_value = 0; enum pdb_policy_type field; char *endptr; + int err = 0; if (argc != 2 || c->display_usage) { d_fprintf(stderr, "%s\n%s", @@ -500,9 +501,9 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv value = -1; } else { - value = strtoul(argv[1], &endptr, 10); + value = strtoul_err(argv[1], &endptr, 10, &err); - if ((endptr == argv[1]) || (endptr[0] != '\0')) { + if ((endptr == argv[1]) || (endptr[0] != '\0') || (err != 0)) { d_printf(_("Unable to set policy \"%s\"! Invalid value " "\"%s\".\n"), account_policy, argv[1]); diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 585f1bfada3..c80d5411b00 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -598,9 +598,14 @@ static int set_user_info(const char *username, const char *fullname, time_t value = get_time_t_max(); if (strcmp(kickoff_time, "never") != 0) { - uint32_t num = strtoul(kickoff_time, &endptr, 10); - - if ((endptr == kickoff_time) || (endptr[0] != '\0')) { + int error = 0; + uint32_t num; + + num = strtoul_err(kickoff_time, &endptr, 10, &error); + if ((endptr == kickoff_time) || + (endptr[0] != '\0') || + (error != 0)) + { fprintf(stderr, "Failed to parse kickoff time\n"); return -1; } diff --git a/source3/utils/regedit_dialog.c b/source3/utils/regedit_dialog.c index dcce66bf208..aeea70ac22e 100644 --- a/source3/utils/regedit_dialog.c +++ b/source3/utils/regedit_dialog.c @@ -1032,6 +1032,7 @@ bool dialog_section_text_field_get_uint(struct dialog_section *section, bool rv; const char *buf; char *endp; + int error = 0; struct dialog_section_text_field *text_field = talloc_get_type_abort(section, struct dialog_section_text_field); @@ -1041,9 +1042,9 @@ bool dialog_section_text_field_get_uint(struct dialog_section *section, if (buf == NULL) { return false; } - *out = strtoull(buf, &endp, 0); + *out = strtoull_err(buf, &endp, 0, &error); rv = true; - if (endp == buf || endp == NULL || endp[0] != '\0') { + if (endp == buf || endp == NULL || endp[0] != '\0' || error != 0) { rv = false; }