lib: Use wrapper for string to integer conversion
authorSwen Schillig <swen@linux.ibm.com>
Mon, 28 Jan 2019 11:54:07 +0000 (12:54 +0100)
committerRalph Boehme <slow@samba.org>
Thu, 28 Feb 2019 11:27:52 +0000 (12:27 +0100)
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>
source3/lib/interface.c
source3/lib/messages_dgm.c
source3/lib/namemap_cache.c
source3/lib/sysquotas.c
source3/lib/tldap_util.c
source3/lib/util_str.c
source3/wscript_build

index a3bc5d24e9114774991747492f577b02fbe434e0..342c92a61a2185bdcb1a6c4d08695f46d56d4310 100644 (file)
@@ -358,6 +358,7 @@ static void parse_extra_info(char *key, uint64_t *speed, uint32_t *cap,
        while (key != NULL && *key != '\0') {
                char *next_key;
                char *val;
+               int error = 0;
 
                next_key = strchr_m(key, ',');
                if (next_key != NULL) {
@@ -369,7 +370,10 @@ static void parse_extra_info(char *key, uint64_t *speed, uint32_t *cap,
                        *val++ = 0;
 
                        if (strequal_m(key, "speed")) {
-                               *speed = (uint64_t)strtoull(val, NULL, 0);
+                               *speed = (uint64_t)strtoull_err(val, NULL, 0, &error);
+                               if (error != 0) {
+                                       DBG_DEBUG("Invalid speed value (%s)\n", val);
+                               }
                        } else if (strequal_m(key, "capability")) {
                                if (strequal_m(val, "RSS")) {
                                        *cap |= FSCTL_NET_IFACE_RSS_CAPABLE;
@@ -380,7 +384,10 @@ static void parse_extra_info(char *key, uint64_t *speed, uint32_t *cap,
                                                    "'%s'\n", val);
                                }
                        } else if (strequal_m(key, "if_index")) {
-                               *if_index = (uint32_t)strtoul(val, NULL, 0);
+                               *if_index = (uint32_t)strtoul_err(val, NULL, 0, &error);
+                               if (error != 0) {
+                                       DBG_DEBUG("Invalid key value (%s)\n", val);
+                               }
                        } else {
                                DBG_DEBUG("Key unknown: '%s'\n", key);
                        }
@@ -515,9 +522,12 @@ static void interpret_interface(char *token)
                        return;
                }
        } else {
+               int error = 0;
                char *endp = NULL;
-               unsigned long val = strtoul(p, &endp, 0);
-               if (p == endp || (endp && *endp != '\0')) {
+               unsigned long val;
+
+               val = strtoul_err(p, &endp, 0, &error);
+               if (p == endp || (endp && *endp != '\0') || error != 0) {
                        DEBUG(2,("interpret_interface: "
                                "can't determine netmask value from %s\n",
                                p));
index 37eefeb0a4a7b8024272f161d4474241ae5aad61..b3e992284426eaa7ce91e7212e3082a54f951f1c 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "replace.h"
+#include "util/util.h"
 #include "system/network.h"
 #include "system/filesys.h"
 #include "system/dir.h"
@@ -1442,6 +1443,7 @@ static int messaging_dgm_read_unique(int fd, uint64_t *punique)
 {
        char buf[25];
        ssize_t rw_ret;
+       int error = 0;
        unsigned long long unique;
        char *endptr;
 
@@ -1451,13 +1453,15 @@ static int messaging_dgm_read_unique(int fd, uint64_t *punique)
        }
        buf[rw_ret] = '\0';
 
-       unique = strtoull(buf, &endptr, 10);
+       unique = strtoull_err(buf, &endptr, 10, &error);
        if ((unique == 0) && (errno == EINVAL)) {
                return EINVAL;
        }
-       if ((unique == ULLONG_MAX) && (errno == ERANGE)) {
-               return ERANGE;
+
+       if (error != 0) {
+               return error;
        }
+
        if (endptr[0] != '\n') {
                return EINVAL;
        }
@@ -1599,6 +1603,7 @@ int messaging_dgm_forall(int (*fn)(pid_t pid, void *private_data),
        struct messaging_dgm_context *ctx = global_dgm_context;
        DIR *msgdir;
        struct dirent *dp;
+       int error = 0;
 
        if (ctx == NULL) {
                return ENOTCONN;
@@ -1621,8 +1626,8 @@ int messaging_dgm_forall(int (*fn)(pid_t pid, void *private_data),
                unsigned long pid;
                int ret;
 
-               pid = strtoul(dp->d_name, NULL, 10);
-               if (pid == 0) {
+               pid = strtoul_err(dp->d_name, NULL, 10, &error);
+               if ((pid == 0) || (error != 0)) {
                        /*
                         * . and .. and other malformed entries
                         */
index fa179517f9f81a4da8c2809e969aa24f848c62ea..42656ede0b7b38e8e0b0aee8856af278f7061c6b 100644 (file)
@@ -22,6 +22,7 @@
 #include "source3/lib/gencache.h"
 #include "lib/util/debug.h"
 #include "lib/util/strv.h"
+#include "lib/util/util.h"
 #include "lib/util/talloc_stack.h"
 #include "lib/util/charset/charset.h"
 #include "libcli/security/dom_sid.h"
@@ -105,6 +106,7 @@ static void namemap_cache_find_sid_parser(
        const char *domain;
        const char *name;
        const char *typebuf;
+       int error = 0;
        char *endptr;
        unsigned long type;
 
@@ -123,11 +125,8 @@ static void namemap_cache_find_sid_parser(
                return;
        }
 
-       type = strtoul(typebuf, &endptr, 10);
-       if (*endptr != '\0') {
-               return;
-       }
-       if ((type == ULONG_MAX) && (errno == ERANGE)) {
+       type = strtoul_err(typebuf, &endptr, 10, &error);
+       if ((*endptr != '\0') || (error != 0)) {
                return;
        }
 
@@ -253,6 +252,7 @@ static void namemap_cache_find_name_parser(
        const char *sid_endptr;
        const char *typebuf;
        char *endptr;
+       int error = 0;
        struct dom_sid sid;
        unsigned long type;
        bool ok;
@@ -276,11 +276,8 @@ static void namemap_cache_find_name_parser(
                return;
        }
 
-       type = strtoul(typebuf, &endptr, 10);
-       if (*endptr != '\0') {
-               return;
-       }
-       if ((type == ULONG_MAX) && (errno == ERANGE)) {
+       type = strtoul_err(typebuf, &endptr, 10, &error);
+       if ((*endptr != '\0') || (error != 0)) {
                return;
        }
 
index 9b2d37b837599e7a54930a28ce2800c529166a0c..c89dc96d69026c077a957c029621fe3c4614dcb7 100644 (file)
@@ -250,6 +250,7 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
                char *p2;
                char *syscmd = NULL;
                int _id = -1;
+               int error = 0;
 
                switch(qtype) {
                        case SMB_USER_QUOTA_TYPE:
@@ -282,7 +283,11 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
 
                        /* we need to deal with long long unsigned here, if supported */
 
-                       dp->qflags = strtoul(line, &p2, 10);
+                       dp->qflags = strtoul_err(line, &p2, 10, &error);
+                       if (error != 0) {
+                               goto invalid_param;
+                       }
+
                        p = p2;
                        while (p && *p && isspace(*p)) {
                                p++;
index 508c6c02f804518fd1bbfa505f2048cdacb16c71..3135a8c439676acb8ae4778b9364eff15c5c2f38 100644 (file)
@@ -389,13 +389,22 @@ bool tldap_pull_uint64(struct tldap_message *msg, const char *attr,
 {
        char *str;
        uint64_t result;
+       int error = 0;
 
        str = tldap_talloc_single_attribute(msg, attr, talloc_tos());
        if (str == NULL) {
                DEBUG(10, ("Could not find attribute %s\n", attr));
                return false;
        }
-       result = strtoull(str, NULL, 10);
+
+       result = strtoull_err(str, NULL, 10, &error);
+       if (error != 0) {
+               DBG_DEBUG("Attribute conversion failed (%s)\n",
+                         strerror(error));
+               TALLOC_FREE(str);
+               return false;
+       }
+
        TALLOC_FREE(str);
        *presult = result;
        return true;
index 8568af46c172f98c50189dc815061b7e3bcf057c..a0095d23978e3b77aa8b03ab234540083e0eacb8 100644 (file)
@@ -851,14 +851,15 @@ uint64_t conv_str_size(const char * str)
 {
         uint64_t lval;
        char * end;
+       int error = 0;
 
         if (str == NULL || *str == '\0') {
                 return 0;
         }
 
-       lval = strtoull(str, &end, 10 /* base */);
+       lval = strtoull_err(str, &end, 10, &error);
 
-        if (end == NULL || end == str) {
+        if (end == NULL || end == str || error != 0) {
                 return 0;
         }
 
index f25a27ba3a8fe87902427ddd3a1881d8ba93ed33..2b5b3ca2c4f491ea5cbf168d898a8190b43749be 100644 (file)
@@ -367,6 +367,7 @@ bld.SAMBA3_LIBRARY('messages_dgm',
                         PTHREADPOOL
                         msghdr
                         genrand
+                       samba-util
                         ''',
                    private_library=True)
 
@@ -1362,6 +1363,7 @@ bld.RECURSE('smbd/notifyd')
 bld.RECURSE('rpcclient')
 bld.RECURSE('utils')
 bld.RECURSE('nmbd')
+bld.RECURSE('lib/util')
 
 bld.ENFORCE_GROUP_ORDERING()
 bld.CHECK_PROJECT_RULES()