common-lib: Use wrapper for string to integer conversion
authorSwen Schillig <swen@linux.ibm.com>
Wed, 30 Jan 2019 07:33:02 +0000 (08:33 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 1 Mar 2019 00:32:11 +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>
lib/ldb-samba/ldb_matching_rules.c
lib/ldb-samba/ldif_handlers.c
lib/param/loadparm.c
lib/util/access.c
lib/util/asn1.c
lib/util/util_str.c

index 2aaaeb7450b15f67f3c11b92199529c909bf1bd0..7387c12f10d89dd3132081d1ed096ef754ff6fdd 100644 (file)
@@ -383,16 +383,22 @@ static int dsdb_match_for_dns_to_tombstone_time(struct ldb_context *ldb,
                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
        } else {
                char *p = NULL;
+               int error = 0;
                char s[value_to_match->length+1];
+
                memcpy(s, value_to_match->data, value_to_match->length);
                s[value_to_match->length] = 0;
                if (s[0] == '\0' || s[0] == '-') {
                        DBG_ERR("Empty timestamp passed\n");
                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
                }
-               tombstone_time = strtoull(s, &p, 10);
-               if (p == NULL || p == s || *p != '\0' ||
-                   tombstone_time == ULLONG_MAX) {
+               tombstone_time = strtoull_err(s, &p, 10, &error);
+               if (p == NULL ||
+                   p == s ||
+                   *p != '\0' ||
+                   error != 0 ||
+                   tombstone_time == ULLONG_MAX)
+               {
                        DBG_ERR("Invalid timestamp string passed\n");
                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
                }
@@ -514,14 +520,21 @@ static int dsdb_match_for_expunge(struct ldb_context *ldb,
                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
        } else {
                char *p = NULL;
+               int error = 0;
                char s[value_to_match->length+1];
+
                memcpy(s, value_to_match->data, value_to_match->length);
                s[value_to_match->length] = 0;
                if (s[0] == '\0' || s[0] == '-') {
                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
                }
-               tombstone_time = strtoull(s, &p, 10);
-               if (p == NULL || p == s || *p != '\0' || tombstone_time == ULLONG_MAX) {
+               tombstone_time = strtoull_err(s, &p, 10, &error);
+               if (p == NULL ||
+                   p == s ||
+                   *p != '\0' ||
+                   error != 0 ||
+                   tombstone_time == ULLONG_MAX)
+               {
                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
                }
        }
index ecc02e51c1dc04566ce9c8363040a68703d286ed..d38cdd0c9a32d7c2c91b0a0a9dad57b264f7dc29 100644 (file)
@@ -596,6 +596,8 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
 
        line = string;
        while (line && line[0]) {
+               int error = 0;
+
                p=strchr(line, ';');
                if (p) {
                        p[0] = '\0';
@@ -619,9 +621,10 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
                        return -1;
                }
 
-               blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix = strtoul(line, &oid, 10);
+               blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix =
+                       strtoul_err(line, &oid, 10, &error);
 
-               if (oid[0] != ':') {
+               if (oid[0] != ':' || error != 0) {
                        talloc_free(tmp_ctx);
                        return -1;
                }
index 84c83ae91ec68b352cbc69a3fc4b1cb468ab1d71..9c7bf8928350bc53333ec4fb75ccc471a0dfc810 100644 (file)
@@ -331,13 +331,21 @@ int lp_int(const char *s)
  */
 unsigned long lp_ulong(const char *s)
 {
+       int error = 0;
+       unsigned long int ret;
 
        if (!s || !*s) {
-               DEBUG(0,("lp_ulong(%s): is called with NULL!\n",s));
+               DBG_DEBUG("lp_ulong(%s): is called with NULL!\n",s);
                return -1;
        }
 
-       return strtoul(s, NULL, 0);
+       ret = strtoul_err(s, NULL, 0, &error);
+       if (error != 0) {
+               DBG_DEBUG("lp_ulong(%s): conversion failed\n",s);
+               return -1;
+       }
+
+       return ret;
 }
 
 /**
@@ -345,13 +353,21 @@ unsigned long lp_ulong(const char *s)
  */
 unsigned long long lp_ulonglong(const char *s)
 {
+       int error = 0;
+       unsigned long long int ret;
 
        if (!s || !*s) {
-               DEBUG(0, ("lp_ulonglong(%s): is called with NULL!\n", s));
+               DBG_DEBUG("lp_ulonglong(%s): is called with NULL!\n", s);
                return -1;
        }
 
-       return strtoull(s, NULL, 0);
+       ret = strtoull_err(s, NULL, 0, &error);
+       if (error != 0) {
+               DBG_DEBUG("lp_ulonglong(%s): conversion failed\n",s);
+               return -1;
+       }
+
+       return ret;
 }
 
 /**
index 7da0573a74d43d3209d0c9309a3dc293babc0a77..a05a47c15b20070998e6b50f3b9cfe29e2757c27 100644 (file)
@@ -71,8 +71,11 @@ static bool masked_match(const char *tok, const char *slash, const char *s)
                }
         } else {
                char *endp = NULL;
-               unsigned long val = strtoul(slash+1, &endp, 0);
-               if (slash+1 == endp || (endp && *endp != '\0')) {
+               int error = 0;
+               unsigned long val;
+
+               val = strtoul_err(slash+1, &endp, 0, &error);
+               if (slash+1 == endp || (endp && *endp != '\0') || error != 0) {
                        return false;
                }
                if (!make_netmask(&ss_mask, &ss_tok, val)) {
index 60ddfa09bcf439cec707ad915feb0e1ff2de4b28..affa8f1df913b33fff6c46070dda4beeab4193d3 100644 (file)
@@ -273,15 +273,20 @@ bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
        const char *p = (const char *)OID;
        char *newp;
        int i;
+       int error = 0;
 
        if (!isdigit(*p)) return false;
-       v = strtoul(p, &newp, 10);
-       if (newp[0] != '.') return false;
+       v = strtoul_err(p, &newp, 10, &error);
+       if (newp[0] != '.' || error != 0) {
+               return false;
+       }
        p = newp + 1;
 
        if (!isdigit(*p)) return false;
-       v2 = strtoul(p, &newp, 10);
-       if (newp[0] != '.') return false;
+       v2 = strtoul_err(p, &newp, 10, &error);
+       if (newp[0] != '.' || error != 0) {
+               return false;
+       }
        p = newp + 1;
 
        /*the ber representation can't use more space than the string one */
@@ -293,8 +298,8 @@ bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
        i = 1;
        while (*p) {
                if (!isdigit(*p)) return false;
-               v = strtoul(p, &newp, 10);
-               if (newp[0] == '.') {
+               v = strtoul_err(p, &newp, 10, &error);
+               if (newp[0] == '.' || error != 0) {
                        p = newp + 1;
                        /* check for empty last component */
                        if (!*p) return false;
index c7d91ca3744b63aa80a13c55b72e1e2296b82f6f..447919b087bbac5be79ca8c3bb8f2ff8702795f2 100644 (file)
@@ -63,13 +63,14 @@ _PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val)
 {
        char *              end = NULL;
        unsigned long long  lval;
+       int error = 0;
 
        if (str == NULL || *str == '\0') {
                return false;
        }
 
-       lval = strtoull(str, &end, 10 /* base */);
-       if (end == NULL || end == str) {
+       lval = strtoull_err(str, &end, 10, &error);
+       if (end == NULL || end == str || error != 0) {
                return false;
        }
 
@@ -104,13 +105,14 @@ _PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val)
 {
        char *              end = NULL;
        unsigned long long  lval;
+       int error = 0;
 
        if (str == NULL || *str == '\0') {
                return false;
        }
 
-       lval = strtoull(str, &end, 10 /* base */);
-       if (end == NULL || *end != '\0' || end == str) {
+       lval = strtoull_err(str, &end, 10, &error);
+       if (end == NULL || *end != '\0' || end == str || error != 0) {
                return false;
        }