Make parsing of piped data in `speed.c` more robust
authorDaniel Fiala <daniel@openssl.org>
Mon, 19 Sep 2022 04:41:58 +0000 (06:41 +0200)
committerTomas Mraz <tomas@openssl.org>
Thu, 24 Nov 2022 09:10:04 +0000 (10:10 +0100)
Fixes openssl#19050

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19238)

apps/speed.c

index 9c6bdefa9d0cca4708021dfe915dcadd3de01546..5be02e8114791ea9715c7bb32870f2909cb0d7cd 100644 (file)
@@ -29,6 +29,7 @@
 #include <math.h>
 #include "apps.h"
 #include "progs.h"
+#include "internal/nelem.h"
 #include "internal/numbers.h"
 #include <openssl/crypto.h>
 #include <openssl/rand.h>
@@ -3445,9 +3446,6 @@ static char *sstrsep(char **string, const char *delim)
     char isdelim[256];
     char *token = *string;
 
-    if (**string == 0)
-        return NULL;
-
     memset(isdelim, 0, sizeof(isdelim));
     isdelim[0] = 1;
 
@@ -3467,6 +3465,23 @@ static char *sstrsep(char **string, const char *delim)
     return token;
 }
 
+static int strtoint(const char *str, const int min_val, const int upper_val,
+                    int *res)
+{
+    char *end = NULL;
+    long int val = 0;
+
+    errno = 0;
+    val = strtol(str, &end, 10);
+    if (errno == 0 && end != str && *end == 0
+        && min_val <= val && val < upper_val) {
+        *res = (int)val;
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
 static int do_multi(int multi, int size_num)
 {
     int n;
@@ -3507,6 +3522,9 @@ static int do_multi(int multi, int size_num)
         FILE *f;
         char buf[1024];
         char *p;
+        char *tk;
+        int k;
+        double d;
 
         if ((f = fdopen(fds[n], "r")) == NULL) {
             BIO_printf(bio_err, "fdopen failure with 0x%x\n",
@@ -3529,93 +3547,87 @@ static int do_multi(int multi, int size_num)
                 int alg;
                 int j;
 
-                alg = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
-                for (j = 0; j < size_num; ++j)
-                    results[alg][j] += atof(sstrsep(&p, sep));
+                if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) {
+                    sstrsep(&p, sep);
+                    for (j = 0; j < size_num; ++j)
+                        results[alg][j] += atof(sstrsep(&p, sep));
+                }
             } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
-                int k;
-                double d;
-
-                k = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
+                tk = sstrsep(&p, sep);
+                if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) {
+                    sstrsep(&p, sep);
 
-                d = atof(sstrsep(&p, sep));
-                rsa_results[k][0] += d;
+                    d = atof(sstrsep(&p, sep));
+                    rsa_results[k][0] += d;
 
-                d = atof(sstrsep(&p, sep));
-                rsa_results[k][1] += d;
+                    d = atof(sstrsep(&p, sep));
+                    rsa_results[k][1] += d;
+                }
             } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
-                int k;
-                double d;
-
-                k = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
+                tk = sstrsep(&p, sep);
+                if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) {
+                    sstrsep(&p, sep);
 
-                d = atof(sstrsep(&p, sep));
-                dsa_results[k][0] += d;
+                    d = atof(sstrsep(&p, sep));
+                    dsa_results[k][0] += d;
 
-                d = atof(sstrsep(&p, sep));
-                dsa_results[k][1] += d;
+                    d = atof(sstrsep(&p, sep));
+                    dsa_results[k][1] += d;
+                }
             } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
-                int k;
-                double d;
-
-                k = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
+                tk = sstrsep(&p, sep);
+                if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) {
+                    sstrsep(&p, sep);
 
-                d = atof(sstrsep(&p, sep));
-                ecdsa_results[k][0] += d;
+                    d = atof(sstrsep(&p, sep));
+                    ecdsa_results[k][0] += d;
 
-                d = atof(sstrsep(&p, sep));
-                ecdsa_results[k][1] += d;
+                    d = atof(sstrsep(&p, sep));
+                    ecdsa_results[k][1] += d;
+                }
             } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
-                int k;
-                double d;
+                tk = sstrsep(&p, sep);
+                if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) {
+                    sstrsep(&p, sep);
 
-                k = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
-
-                d = atof(sstrsep(&p, sep));
-                ecdh_results[k][0] += d;
+                    d = atof(sstrsep(&p, sep));
+                    ecdh_results[k][0] += d;
+                }
             } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
-                int k;
-                double d;
-
-                k = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
-                sstrsep(&p, sep);
+                tk = sstrsep(&p, sep);
+                if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
+                    sstrsep(&p, sep);
+                    sstrsep(&p, sep);
 
-                d = atof(sstrsep(&p, sep));
-                eddsa_results[k][0] += d;
+                    d = atof(sstrsep(&p, sep));
+                    eddsa_results[k][0] += d;
 
-                d = atof(sstrsep(&p, sep));
-                eddsa_results[k][1] += d;
+                    d = atof(sstrsep(&p, sep));
+                    eddsa_results[k][1] += d;
+                }
 # ifndef OPENSSL_NO_SM2
             } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
-                int k;
-                double d;
-
-                k = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
-                sstrsep(&p, sep);
+                tk = sstrsep(&p, sep);
+                if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
+                    sstrsep(&p, sep);
+                    sstrsep(&p, sep);
 
-                d = atof(sstrsep(&p, sep));
-                sm2_results[k][0] += d;
+                    d = atof(sstrsep(&p, sep));
+                    sm2_results[k][0] += d;
 
-                d = atof(sstrsep(&p, sep));
-                sm2_results[k][1] += d;
+                    d = atof(sstrsep(&p, sep));
+                    sm2_results[k][1] += d;
+                }
 # endif /* OPENSSL_NO_SM2 */
 # ifndef OPENSSL_NO_DH
             } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
-                int k;
-                double d;
+                tk = sstrsep(&p, sep);
+                if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
+                    sstrsep(&p, sep);
 
-                k = atoi(sstrsep(&p, sep));
-                sstrsep(&p, sep);
-
-                d = atof(sstrsep(&p, sep));
-                ffdh_results[k][0] += d;
+                    d = atof(sstrsep(&p, sep));
+                    ffdh_results[k][0] += d;
+                }
 # endif /* OPENSSL_NO_DH */
             } else if (!HAS_PREFIX(buf, "+H:")) {
                 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,