truncation check some snprintf calls (over-cautiously in case)
authorderaadt <deraadt@openbsd.org>
Sat, 19 Apr 2014 16:18:22 +0000 (16:18 +0000)
committerderaadt <deraadt@openbsd.org>
Sat, 19 Apr 2014 16:18:22 +0000 (16:18 +0000)
ok jsing beck

lib/libssl/src/apps/apps.c
lib/libssl/src/apps/enc.c
lib/libssl/src/apps/req.c
lib/libssl/src/apps/s_time.c

index 0536aa6..6413d5c 100644 (file)
@@ -1436,7 +1436,7 @@ save_serial(char *serialfile, char *suffix, BIGNUM * serial,
 {
        char buf[1][BSIZE];
        BIO *out = NULL;
-       int ret = 0;
+       int ret = 0, n;
        ASN1_INTEGER *ai = NULL;
        int j;
 
@@ -1449,9 +1449,13 @@ save_serial(char *serialfile, char *suffix, BIGNUM * serial,
                goto err;
        }
        if (suffix == NULL)
-               strlcpy(buf[0], serialfile, BSIZE);
+               n = strlcpy(buf[0], serialfile, BSIZE);
        else
-               snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
+               n = snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
+       if (n == -1 || n >= sizeof(buf[0])) {
+               BIO_printf(bio_err, "serial too long\n");
+               goto err;
+       }
 #ifdef RL_DEBUG
        BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
 #endif
index c8f0410..5a0dca5 100644 (file)
@@ -387,10 +387,15 @@ enc_main(int argc, char **argv)
        if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) {
                for (;;) {
                        char buf[200];
+                       int ret;
 
-                       snprintf(buf, sizeof buf, "enter %s %s password:",
+                       ret = snprintf(buf, sizeof buf, "enter %s %s password:",
                            OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
                            (enc) ? "encryption" : "decryption");
+                       if (ret == -1 || ret >= sizeof buf) {
+                               BIO_printf(bio_err, "Password prompt too long\n");
+                               goto end;
+                       }
                        strbuf[0] = '\0';
                        i = EVP_read_pw_string((char *) strbuf, SIZE, buf, enc);
                        if (i == 0) {
index 38428f8..8fac592 100644 (file)
@@ -1074,24 +1074,40 @@ start:          for (;;) {
                                goto start;
                        ret = snprintf(buf, sizeof buf, "%s_default", v->name);
                        if (ret == -1 || ret >= sizeof(buf)) {
-                               BIO_printf(bio_err, "Name '%s' too long\n", v->name);
+                               BIO_printf(bio_err, "Name '%s' too long for default\n",
+                                   v->name);
                                return 0;
                        }
                        if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
                                ERR_clear_error();
                                def = "";
                        }
-                       snprintf(buf, sizeof buf, "%s_value", v->name);
+                       ret = snprintf(buf, sizeof buf, "%s_value", v->name);
+                       if (ret == -1 || ret >= sizeof(buf)) {
+                               BIO_printf(bio_err, "Name '%s' too long for value\n",
+                                   v->name);
+                               return 0;
+                       }
                        if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
                                ERR_clear_error();
                                value = NULL;
                        }
-                       snprintf(buf, sizeof buf, "%s_min", v->name);
+                       ret = snprintf(buf, sizeof buf, "%s_min", v->name);
+                       if (ret == -1 || ret >= sizeof(buf)) {
+                               BIO_printf(bio_err, "Name '%s' too long for min\n",
+                                   v->name);
+                               return 0;
+                       }
                        if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
                                ERR_clear_error();
                                n_min = -1;
                        }
-                       snprintf(buf, sizeof buf, "%s_max", v->name);
+                       ret = snprintf(buf, sizeof buf, "%s_max", v->name);
+                       if (ret == -1 || ret >= sizeof(buf)) {
+                               BIO_printf(bio_err, "Name '%s' too long for max\n",
+                                   v->name);
+                               return 0;
+                       }
                        if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
                                ERR_clear_error();
                                n_max = -1;
@@ -1105,12 +1121,15 @@ start:          for (;;) {
                        return 0;
                }
                if (attribs) {
-                       if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch)) {
-                               BIO_printf(bio_err, "\nPlease enter the following 'extra' attributes\n");
-                               BIO_printf(bio_err, "to be sent with your certificate request\n");
+                       if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) &&
+                           (!batch)) {
+                               BIO_printf(bio_err,
+                                   "\nPlease enter the following 'extra' attributes\n");
+                               BIO_printf(bio_err,
+                                   "to be sent with your certificate request\n");
                        }
                        i = -1;
-       start2: for (;;) {
+start2:                        for (;;) {
                                int ret;
                                i++;
                                if ((attr_sk == NULL) ||
@@ -1123,7 +1142,8 @@ start:            for (;;) {
                                        goto start2;
                                ret = snprintf(buf, sizeof buf, "%s_default", type);
                                if (ret == -1 || ret >= sizeof(buf)) {
-                                       BIO_printf(bio_err, "Name '%s' too long\n", v->name);
+                                       BIO_printf(bio_err, "Name '%s' too long for default\n",
+                                           v->name);
                                        return 0;
                                }
                                if ((def = NCONF_get_string(req_conf, attr_sect, buf))
@@ -1131,18 +1151,33 @@ start:          for (;;) {
                                        ERR_clear_error();
                                        def = "";
                                }
-                               snprintf(buf, sizeof buf, "%s_value", type);
+                               ret = snprintf(buf, sizeof buf, "%s_value", type);
+                               if (ret == -1 || ret >= sizeof(buf)) {
+                                       BIO_printf(bio_err, "Name '%s' too long for value\n",
+                                           v->name);
+                                       return 0;
+                               }
                                if ((value = NCONF_get_string(req_conf, attr_sect, buf))
                                    == NULL) {
                                        ERR_clear_error();
                                        value = NULL;
                                }
-                               snprintf(buf, sizeof buf, "%s_min", type);
+                               ret = snprintf(buf, sizeof buf, "%s_min", type);
+                               if (ret == -1 || ret >= sizeof(buf)) {
+                                       BIO_printf(bio_err, "Name '%s' too long for min\n",
+                                           v->name);
+                                       return 0;
+                               }
                                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
                                        ERR_clear_error();
                                        n_min = -1;
                                }
-                               snprintf(buf, sizeof buf, "%s_max", type);
+                               ret = snprintf(buf, sizeof buf, "%s_max", type);
+                               if (ret == -1 || ret >= sizeof(buf)) {
+                                       BIO_printf(bio_err, "Name '%s' too long for max\n",
+                                           v->name);
+                                       return 0;
+                               }
                                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
                                        ERR_clear_error();
                                        n_max = -1;
index e7fc7e2..169a9d7 100644 (file)
@@ -398,7 +398,12 @@ s_time_main(int argc, char **argv)
                        goto end;
 
                if (s_www_path != NULL) {
-                       snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_www_path);
+                       int ret = snprintf(buf, sizeof buf,
+                           "GET %s HTTP/1.0\r\n\r\n", s_www_path);
+                       if (ret == -1 || ret >= sizeof buf) {
+                               fprintf(stderr, "URL too long\n");
+                               goto end;
+                       }
                        SSL_write(scon, buf, strlen(buf));
                        while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
                                bytes_read += i;
@@ -453,7 +458,12 @@ next:
                goto end;
        }
        if (s_www_path != NULL) {
-               snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_www_path);
+               int ret = snprintf(buf, sizeof buf,
+                   "GET %s HTTP/1.0\r\n\r\n", s_www_path);
+               if (ret == -1 || ret >= sizeof buf) {
+                       fprintf(stderr, "URL too long\n");
+                       goto end;
+               }
                SSL_write(scon, buf, strlen(buf));
                while (SSL_read(scon, buf, sizeof(buf)) > 0);
        }
@@ -490,7 +500,12 @@ next:
                        goto end;
 
                if (s_www_path) {
-                       snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_www_path);
+                       int ret = snprintf(buf, sizeof buf,
+                           "GET %s HTTP/1.0\r\n\r\n", s_www_path);
+                       if (ret == -1 || ret >= sizeof buf) {
+                               fprintf(stderr, "URL too long\n");
+                               goto end;
+                       }
                        SSL_write(scon, buf, strlen(buf));
                        while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
                                bytes_read += i;