utils: Use wrapper for string to integer conversion
authorSwen Schillig <swen@linux.ibm.com>
Mon, 28 Jan 2019 12:36:45 +0000 (13:36 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 1 Mar 2019 00:32:10 +0000 (00:32 +0000)
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 <swen@linux.ibm.com>
Reviewed-by: Ralph Böhme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/utils/net_idmap.c
source3/utils/net_registry.c
source3/utils/net_rpc_registry.c
source3/utils/net_sam.c
source3/utils/pdbedit.c
source3/utils/regedit_dialog.c

index b49d5f43381ba8b016a4121c84a22c27b588772f..f6c9f3a1a3d4a4cda30c4d9557da31bd9262ff6b 100644 (file)
@@ -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 */
index 01a36b20e7cd96b537298c669e30905ec8529711..74224ddbf15a5d3eac295bf67e70b50b49fc797c 100644 (file)
@@ -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"),
index 19b73fd7042f3c28762cf719749c48ff42ff5e04..84936ee31aea4dce29cb310d70be534498443ec9 100644 (file)
@@ -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);
index 5a9d1792d51ba35e018f710e63e4d6d8bcff7325..fc2a7baacef4cef5b666b9135b1133027264c4ee 100644 (file)
@@ -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]);
index 585f1bfada324821cedb81e831bd786649f6b15b..c80d5411b0026c170379e0d43f2527cfb9efc4d8 100644 (file)
@@ -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;
                        }
index dcce66bf20838b2d1685ea50f67387db53dc7f08..aeea70ac22e5c4e411c0488cd3bdc083e3a131cb 100644 (file)
@@ -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;
        }