Check for NULL conf in NCONF_get_number
authorPauli <paul.dale@oracle.com>
Mon, 2 Jul 2018 22:02:37 +0000 (08:02 +1000)
committerPauli <paul.dale@oracle.com>
Tue, 3 Jul 2018 03:14:17 +0000 (13:14 +1000)
The problematic case falls back to a NULL conf which returns the result
of getenv(2).  If this returns NULL, everything was good.  If this returns
a string an attempt to convert it to a number is made using the function
pointers from conf.

This fix uses the strtol(3) function instead, we don't have the
configuration settings and this behaves as the default would.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6632)

crypto/conf/conf_lib.c
test/conf_include_test.c

index c72511ba67eae8abe37e68d2cb1706f9b64a75a0..5f976f35c428639fdde436c0e370d3dbfb499f93 100644 (file)
@@ -292,10 +292,13 @@ int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
     if (str == NULL)
         return 0;
 
     if (str == NULL)
         return 0;
 
-    for (*result = 0; conf->meth->is_number(conf, *str);) {
-        *result = (*result) * 10 + conf->meth->to_int(conf, *str);
-        str++;
-    }
+    if (conf == NULL)
+        *result = strtol(str, &str, 10);
+    else
+        for (*result = 0; conf->meth->is_number(conf, *str);) {
+            *result = (*result) * 10 + conf->meth->to_int(conf, *str);
+            str++;
+        }
 
     return 1;
 }
 
     return 1;
 }
index 7f99d3b15f1de223d1fce47cb2740213dcd518b6..ba79d2c208a46604296e619dc9e2b4dff373e5cd 100644 (file)
@@ -123,6 +123,36 @@ static int test_load_config(void)
     return 1;
 }
 
     return 1;
 }
 
+static int test_check_null_numbers(void)
+{
+#if defined(_BSD_SOURCE) \
+        || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
+        || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
+    long val = 0;
+
+    /* Verify that a NULL config with a present environment variable returns
+     * success and the value.
+     */
+    if (!TEST_int_eq(setenv("FNORD", "123", 1), 0)
+            || !TEST_true(NCONF_get_number(NULL, "missing", "FNORD", &val))
+            || !TEST_long_eq(val, 123)) {
+        TEST_note("environment variable with NULL conf failed");
+        return 0;
+    }
+
+    /*
+     * Verify that a NULL config with a missing envrionment variable returns
+     * a failure code.
+     */
+    if (!TEST_int_eq(unsetenv("FNORD"), 0)
+            || !TEST_false(NCONF_get_number(NULL, "missing", "FNORD", &val))) {
+        TEST_note("missing environment variable with NULL conf failed");
+        return 0;
+    }
+#endif
+    return 1;
+}
+
 int setup_tests(void)
 {
     const char *conf_file;
 int setup_tests(void)
 {
     const char *conf_file;
@@ -150,6 +180,7 @@ int setup_tests(void)
     change_path(conf_file);
 
     ADD_TEST(test_load_config);
     change_path(conf_file);
 
     ADD_TEST(test_load_config);
+    ADD_TEST(test_check_null_numbers);
     return 1;
 }
 
     return 1;
 }