From 2e1a1681ec83a249a8613d9fc0671c5634c6a08c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 11 Jun 2018 13:39:49 -0700 Subject: [PATCH 1/5] GCC-8 string fixes 1. strncat() does not like to copy single byte strings with "n = 1", as it won't null-terminate. 2. strncpy()'s len parameter is the size of the dst not the src. 3. Replaced the echoserver HTTP response composition of const strings with a copy of a single string. --- examples/echoserver/echoserver.c | 26 ++++++------- wolfcrypt/src/wc_port.c | 65 +++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 985189645..2fad2307e 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -379,22 +379,18 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) break; } #endif - if ( strncmp(command, "GET", 3) == 0) { - char type[] = "HTTP/1.0 200 ok\r\nContent-type:" - " text/html\r\n\r\n"; - char header[] = "\n
\n";
-                char body[]   = "greetings from wolfSSL\n";
-                char footer[] = "\r\n\r\n";
+            if (strncmp(command, "GET", 3) == 0) {
+                const char resp[] =
+                    "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"
+                    "
\r\n"
+                    "greetings from wolfSSL\r\n\r\n\r\n";
 
-                strncpy(command, type, sizeof(type));
-                echoSz = sizeof(type) - 1;
-
-                strncpy(&command[echoSz], header, sizeof(header));
-                echoSz += (int)sizeof(header) - 1;
-                strncpy(&command[echoSz], body, sizeof(body));
-                echoSz += (int)sizeof(body) - 1;
-                strncpy(&command[echoSz], footer, sizeof(footer));
-                echoSz += (int)sizeof(footer);
+                echoSz = (int)strlen(resp) + 1;
+                if (echoSz > (int)sizeof(command)) {
+                    /* Internal error. */
+                    err_sys("HTTP response greater than buffer.");
+                }
+                strncpy(command, resp, sizeof(command));
 
                 do {
                     err = 0; /* reset error */
diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c
index a9290dcd7..9e6884e13 100644
--- a/wolfcrypt/src/wc_port.c
+++ b/wolfcrypt/src/wc_port.c
@@ -247,6 +247,8 @@ int wolfCrypt_Cleanup(void)
 int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
 {
     int ret = -1; /* default to no files found */
+    int pathLen = 0;
+    int dnameLen = 0;
 
     if (name)
         *name = NULL;
@@ -256,10 +258,14 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
     }
 
     XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
+    pathLen = (int)XSTRLEN(path);
 
 #ifdef USE_WINDOWS_API
-    XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 4);
-    XSTRNCAT(ctx->name, "\\*", 3);
+    if (pathLen > MAX_FILENAME_SZ - 3)
+        return BAD_PATH_ERROR;
+
+    XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3);
+    XSTRNCPY(ctx->name + pathLen, "\\*", MAX_FILENAME_SZ - pathLen);
 
     ctx->hFind = FindFirstFileA(ctx->name, &ctx->FindFileData);
     if (ctx->hFind == INVALID_HANDLE_VALUE) {
@@ -269,9 +275,16 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
 
     do {
         if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
-            XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3);
-            XSTRNCAT(ctx->name, "\\", 2);
-            XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2);
+            dnameLen = (int)XSTRLEN(ctx->entry->d_name);
+
+            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
+                return BAD_PATH_ERROR;
+            }
+            XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+            ctx->name[pathLen] = '\\';
+            XSTRNCPY(ctx->name + pathLen + 1,
+                     ctx->FindFileData.cFileName,
+                     MAX_FILENAME_SZ - pathLen - 1);
             if (name)
                 *name = ctx->name;
             return 0;
@@ -285,9 +298,16 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
     }
 
     while ((ctx->entry = readdir(ctx->dir)) != NULL) {
-        XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2);
-        XSTRNCAT(ctx->name, "/", 1);
-        XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2);
+        dnameLen = (int)XSTRLEN(ctx->entry->d_name);
+
+        if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
+            ret = BAD_PATH_ERROR;
+            break;
+        }
+        XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+        ctx->name[pathLen] = '/';
+        XSTRNCPY(ctx->name + pathLen + 1,
+                 ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1);
 
         if (stat(ctx->name, &ctx->s) != 0) {
             WOLFSSL_MSG("stat on name failed");
@@ -309,6 +329,8 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
 int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
 {
     int ret = -1; /* default to no file found */
+    int pathLen = 0;
+    int dnameLen = 0;
 
     if (name)
         *name = NULL;
@@ -318,13 +340,21 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
     }
 
     XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
+    pathLen = (int)XSTRLEN(path);
 
 #ifdef USE_WINDOWS_API
     while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) {
         if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
-            XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3);
-            XSTRNCAT(ctx->name, "\\", 2);
-            XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2);
+            dnameLen = (int)XSTRLEN(ctx->entry->d_name);
+
+            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
+                return BAD_PATH_ERROR;
+            }
+            XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+            ctx->name[pathLen] = '\\';
+            XSTRNCPY(ctx->name + pathLen + 1,
+                     ctx->FindFileData.cFileName,
+                     MAX_FILENAME_SZ - pathLen - 1);
             if (name)
                 *name = ctx->name;
             return 0;
@@ -332,9 +362,16 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
     }
 #else
     while ((ctx->entry = readdir(ctx->dir)) != NULL) {
-        XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2);
-        XSTRNCAT(ctx->name, "/", 1);
-        XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2);
+        dnameLen = (int)XSTRLEN(ctx->entry->d_name);
+
+        if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
+            ret = BAD_PATH_ERROR;
+            break;
+        }
+        XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+        ctx->name[pathLen] = '/';
+        XSTRNCPY(ctx->name + pathLen + 1,
+                 ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1);
 
         if (stat(ctx->name, &ctx->s) != 0) {
             WOLFSSL_MSG("stat on name failed");

From ed208efc4d49d1efc0c9b81f73333550c806dbce Mon Sep 17 00:00:00 2001
From: John Safranek 
Date: Wed, 20 Jun 2018 15:55:03 -0700
Subject: [PATCH 2/5] GCC-8 string fixes 1. Modify wolfSSL_get_ciphers() to
 limit the XSTRNCPY based on the dst buf length, not the src string.

---
 src/ssl.c | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/src/ssl.c b/src/ssl.c
index 5a5383765..d3cc2f196 100644
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -692,30 +692,25 @@ char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
 int wolfSSL_get_ciphers(char* buf, int len)
 {
     const CipherSuiteInfo* ciphers = GetCipherNames();
-    int  totalInc = 0;
-    int  step     = 0;
-    char delim    = ':';
-    int  size     = GetCipherNamesSize();
-    int  i;
+    int ciphersSz = GetCipherNamesSize();
+    int i;
+    int cipherNameSz;
 
     if (buf == NULL || len <= 0)
         return BAD_FUNC_ARG;
 
     /* Add each member to the buffer delimited by a : */
-    for (i = 0; i < size; i++) {
-        step = (int)(XSTRLEN(ciphers[i].name) + 1);  /* delimiter */
-        totalInc += step;
+    for (i = 0; i < ciphersSz; i++) {
+        cipherNameSz = (int)XSTRLEN(ciphers[i].name);
+        if (cipherNameSz + 1 < len) {
+            XSTRNCPY(buf, ciphers[i].name, len);
+            buf += cipherNameSz;
 
-        /* Check to make sure buf is large enough and will not overflow */
-        if (totalInc < len) {
-            size_t cipherLen = XSTRLEN(ciphers[i].name);
-            XSTRNCPY(buf, ciphers[i].name, cipherLen);
-            buf += cipherLen;
+            if (i < ciphersSz - 1)
+                *buf++ = ':';
+            *buf = 0;
 
-            if (i < size - 1)
-                *buf++ = delim;
-            else
-                *buf++ = '\0';
+            len -= cipherNameSz + 1;
         }
         else
             return BUFFER_E;

From af89458af0e8e20cc53e31c5dbb67e8239187736 Mon Sep 17 00:00:00 2001
From: John Safranek 
Date: Thu, 21 Jun 2018 10:09:26 -0700
Subject: [PATCH 3/5] GCC-8 string fixes 1. strncpy needs to include the source
 string's NULL. 2. Deleted a few redundant string modifications.

---
 src/crl.c           |  3 +--
 src/sniffer.c       |  3 ++-
 src/ssl.c           |  8 +++---
 src/wolfio.c        | 42 ++++++++++++++---------------
 wolfcrypt/src/asn.c | 66 ++++++++++++++++++++++-----------------------
 5 files changed, 60 insertions(+), 62 deletions(-)

diff --git a/src/crl.c b/src/crl.c
index 59b2bcb63..93a77eec5 100644
--- a/src/crl.c
+++ b/src/crl.c
@@ -1045,8 +1045,7 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
         pathLen = (word32)XSTRLEN(path);
         pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR);
         if (pathBuf) {
-            XSTRNCPY(pathBuf, path, pathLen);
-            pathBuf[pathLen] = '\0'; /* Null Terminate */
+            XSTRNCPY(pathBuf, path, pathLen+1);
 
             if (type == WOLFSSL_FILETYPE_PEM) {
                 /* free old path before setting a new one */
diff --git a/src/sniffer.c b/src/sniffer.c
index 9f27ee97f..2feec52f9 100644
--- a/src/sniffer.c
+++ b/src/sniffer.c
@@ -252,7 +252,8 @@ static const char* const msgTable[] =
 /* *nix version uses table above */
 static void GetError(int idx, char* str)
 {
-    XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN);
+    XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN-1);
+    str[MAX_ERROR_LEN-1] = '\0';
 }
 
 
diff --git a/src/ssl.c b/src/ssl.c
index d3cc2f196..ed1336b52 100644
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -10733,8 +10733,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
             ssl->arrays->server_hint[0] = 0;
         else {
             XSTRNCPY(ssl->arrays->server_hint, hint,
-                                            sizeof(ssl->arrays->server_hint));
-            ssl->arrays->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
+                                            sizeof(ssl->arrays->server_hint)-1);
+            ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
         }
         return WOLFSSL_SUCCESS;
     }
@@ -16513,7 +16513,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
                         tmp[sizeof(tmp) - 1] = '\0';
                         if (mp_leading_bit(&rsa.n)) {
                             lbit = 1;
-                            XSTRNCAT(tmp, "00", sizeof("00"));
+                            XSTRNCAT(tmp, "00", 3);
                         }
 
                         rawLen = mp_unsigned_bin_size(&rsa.n);
@@ -25714,7 +25714,7 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
         return WOLFSSL_FAILURE;
     }
     XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz);
-    XSTRNCAT((char*)*cipherInfo, ",", 1);
+    XSTRNCAT((char*)*cipherInfo, ",", 2);
 
     idx = (word32)XSTRLEN((char*)*cipherInfo);
     cipherInfoSz -= idx;
diff --git a/src/wolfio.c b/src/wolfio.c
index 72d86fa87..344b12f8b 100644
--- a/src/wolfio.c
+++ b/src/wolfio.c
@@ -1185,33 +1185,33 @@ int wolfIO_HttpBuildRequest(const char* reqType, const char* domainName,
     if (maxLen > (word32)bufSize)
         return 0;
 
-    XSTRNCPY((char*)buf, reqType, reqTypeLen);
-    buf += reqTypeLen;
-    XSTRNCPY((char*)buf, blankStr, blankStrLen+1);
-    buf += blankStrLen;
-    XSTRNCPY((char*)buf, path, pathLen);
-    buf += pathLen;
-    XSTRNCPY((char*)buf, http11Str, http11StrLen+1);
-    buf += http11StrLen;
+    XSTRNCPY((char*)buf, reqType, bufSize);
+    buf += reqTypeLen; bufSize -= reqTypeLen;
+    XSTRNCPY((char*)buf, blankStr, bufSize);
+    buf += blankStrLen; bufSize -= blankStrLen;
+    XSTRNCPY((char*)buf, path, bufSize);
+    buf += pathLen; bufSize -= pathLen;
+    XSTRNCPY((char*)buf, http11Str, bufSize);
+    buf += http11StrLen; bufSize -= http11StrLen;
     if (domainNameLen > 0) {
-        XSTRNCPY((char*)buf, hostStr, hostStrLen+1);
-        buf += hostStrLen;
-        XSTRNCPY((char*)buf, domainName, domainNameLen);
-        buf += domainNameLen;
+        XSTRNCPY((char*)buf, hostStr, bufSize);
+        buf += hostStrLen; bufSize -= hostStrLen;
+        XSTRNCPY((char*)buf, domainName, bufSize);
+        buf += domainNameLen; bufSize -= domainNameLen;
     }
     if (reqSz > 0 && reqSzStrLen > 0) {
-        XSTRNCPY((char*)buf, contentLenStr, contentLenStrLen+1);
-        buf += contentLenStrLen;
-        XSTRNCPY((char*)buf, reqSzStr, reqSzStrLen);
-        buf += reqSzStrLen;
+        XSTRNCPY((char*)buf, contentLenStr, bufSize);
+        buf += contentLenStrLen; bufSize -= contentLenStrLen;
+        XSTRNCPY((char*)buf, reqSzStr, bufSize);
+        buf += reqSzStrLen; bufSize -= reqSzStrLen;
     }
     if (contentTypeLen > 0) {
-        XSTRNCPY((char*)buf, contentTypeStr, contentTypeStrLen+1);
-        buf += contentTypeStrLen;
-        XSTRNCPY((char*)buf, contentType, contentTypeLen);
-        buf += contentTypeLen;
+        XSTRNCPY((char*)buf, contentTypeStr, bufSize);
+        buf += contentTypeStrLen; bufSize -= contentTypeStrLen;
+        XSTRNCPY((char*)buf, contentType, bufSize);
+        buf += contentTypeLen; bufSize -= contentTypeLen;
     }
-    XSTRNCPY((char*)buf, doubleCrLfStr, doubleCrLfStrLen+1);
+    XSTRNCPY((char*)buf, doubleCrLfStr, bufSize);
     buf += doubleCrLfStrLen;
 
 #ifdef WOLFIO_DEBUG
diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c
index 8b7282caf..a06492227 100644
--- a/wolfcrypt/src/asn.c
+++ b/wolfcrypt/src/asn.c
@@ -4564,24 +4564,23 @@ int GetTimeString(byte* date, int format, char* buf, int len)
     /* place month in buffer */
     buf[0] = '\0';
     switch(t.tm_mon) {
-        case 0:  XSTRNCAT(buf, "Jan ", 4); break;
-        case 1:  XSTRNCAT(buf, "Feb ", 4); break;
-        case 2:  XSTRNCAT(buf, "Mar ", 4); break;
-        case 3:  XSTRNCAT(buf, "Apr ", 4); break;
-        case 4:  XSTRNCAT(buf, "May ", 4); break;
-        case 5:  XSTRNCAT(buf, "Jun ", 4); break;
-        case 6:  XSTRNCAT(buf, "Jul ", 4); break;
-        case 7:  XSTRNCAT(buf, "Aug ", 4); break;
-        case 8:  XSTRNCAT(buf, "Sep ", 4); break;
-        case 9:  XSTRNCAT(buf, "Oct ", 4); break;
-        case 10: XSTRNCAT(buf, "Nov ", 4); break;
-        case 11: XSTRNCAT(buf, "Dec ", 4); break;
+        case 0:  XSTRNCAT(buf, "Jan ", 5); break;
+        case 1:  XSTRNCAT(buf, "Feb ", 5); break;
+        case 2:  XSTRNCAT(buf, "Mar ", 5); break;
+        case 3:  XSTRNCAT(buf, "Apr ", 5); break;
+        case 4:  XSTRNCAT(buf, "May ", 5); break;
+        case 5:  XSTRNCAT(buf, "Jun ", 5); break;
+        case 6:  XSTRNCAT(buf, "Jul ", 5); break;
+        case 7:  XSTRNCAT(buf, "Aug ", 5); break;
+        case 8:  XSTRNCAT(buf, "Sep ", 5); break;
+        case 9:  XSTRNCAT(buf, "Oct ", 5); break;
+        case 10: XSTRNCAT(buf, "Nov ", 5); break;
+        case 11: XSTRNCAT(buf, "Dec ", 5); break;
         default:
             return 0;
 
     }
     idx = 4; /* use idx now for char buffer */
-    buf[idx] = ' ';
 
     XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
               t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
@@ -7725,19 +7724,23 @@ static int wc_EncryptedInfoParse(EncryptedInfo* info,
 #endif /* WOLFSSL_PEM_TO_DER */
 
 #ifdef WOLFSSL_DER_TO_PEM
-static int wc_EncryptedInfoAppend(char* dest, char* cipherInfo)
+static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
 {
     if (cipherInfo != NULL) {
-        size_t cipherInfoStrLen = XSTRLEN(cipherInfo);
+        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
+
         if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
             cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
 
-        XSTRNCAT(dest, kProcTypeHeader, 9);
-        XSTRNCAT(dest, ": 4,ENCRYPTED\n", 14);
-        XSTRNCAT(dest, kDecInfoHeader, 8);
-        XSTRNCAT(dest, ": ", 2);
-        XSTRNCAT(dest, cipherInfo, cipherInfoStrLen);
-        XSTRNCAT(dest, "\n\n", 3);
+        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
+            /* strncat's src length needs to include the NULL */
+            XSTRNCAT(dest, kProcTypeHeader, 10);
+            XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
+            XSTRNCAT(dest, kDecInfoHeader, 9);
+            XSTRNCAT(dest, ": ", 3);
+            XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1);
+            XSTRNCAT(dest, "\n\n", 4);
+        }
     }
     return 0;
 }
@@ -7794,20 +7797,18 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
     }
 #endif
 
-    /* null term and leave room for newline */
-    header[--headerLen] = '\0'; header[--headerLen] = '\0';
-    footer[--footerLen] = '\0'; footer[--footerLen] = '\0';
-
     /* build header and footer based on type */
-    XSTRNCPY(header, headerStr, headerLen);
-    XSTRNCPY(footer, footerStr, footerLen);
+    XSTRNCPY(header, headerStr, headerLen - 1);
+    header[headerLen - 1] = 0;
+    XSTRNCPY(footer, footerStr, footerLen - 1);
+    footer[footerLen - 1] = 0;
 
     /* add new line to end */
     XSTRNCAT(header, "\n", 2);
     XSTRNCAT(footer, "\n", 2);
 
 #ifdef WOLFSSL_ENCRYPTED_KEYS
-    err = wc_EncryptedInfoAppend(header, (char*)cipher_info);
+    err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);
     if (err != 0) {
     #ifdef WOLFSSL_SMALL_STACK
         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
@@ -9667,8 +9668,7 @@ static int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
     if (str == NULL)
         return MEMORY_E;
 
-    XSTRNCPY(str, in, len);
-    str[len] = '\0';
+    XSTRNCPY(str, in, len+1);
 
     nb_val = 0;
 
@@ -11439,8 +11439,7 @@ int wc_SetKeyUsage(Cert *cert, const char *value)
     if (str == NULL)
         return MEMORY_E;
 
-    XSTRNCPY(str, value, len);
-    str[len] = '\0';
+    XSTRNCPY(str, value, len+1);
 
     /* parse value, and set corresponding Key Usage value */
     if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
@@ -11499,8 +11498,7 @@ int wc_SetExtKeyUsage(Cert *cert, const char *value)
     if (str == NULL)
         return MEMORY_E;
 
-    XSTRNCPY(str, value, len);
-    str[len] = '\0';
+    XSTRNCPY(str, value, len+1);
 
     /* parse value, and set corresponding Key Usage value */
     if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {

From 7053830628a185cdc9eb0c1fb5d58f56dc930cab Mon Sep 17 00:00:00 2001
From: John Safranek 
Date: Fri, 22 Jun 2018 11:36:25 -0700
Subject: [PATCH 4/5] GCC-8 string fixes Fix for the Windows directory search
 code.

---
 wolfcrypt/src/wc_port.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c
index 9e6884e13..c8723e4c8 100644
--- a/wolfcrypt/src/wc_port.c
+++ b/wolfcrypt/src/wc_port.c
@@ -275,7 +275,7 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
 
     do {
         if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
-            dnameLen = (int)XSTRLEN(ctx->entry->d_name);
+            dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
 
             if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
                 return BAD_PATH_ERROR;
@@ -345,7 +345,7 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
 #ifdef USE_WINDOWS_API
     while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) {
         if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
-            dnameLen = (int)XSTRLEN(ctx->entry->d_name);
+            dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
 
             if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
                 return BAD_PATH_ERROR;

From f5b3de6b542e202eceba8529b4da2a9ce6b9aade Mon Sep 17 00:00:00 2001
From: John Safranek 
Date: Tue, 31 Jul 2018 13:50:33 -0700
Subject: [PATCH 5/5] GCC-8 string fixes 1. Found one more case where a string
 is copied, potentially without the null. In wc_ports w.r.t. directory and
 file names.

---
 wolfcrypt/src/wc_port.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c
index c8723e4c8..b1e81f846 100644
--- a/wolfcrypt/src/wc_port.c
+++ b/wolfcrypt/src/wc_port.c
@@ -280,7 +280,7 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
             if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
                 return BAD_PATH_ERROR;
             }
-            XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+            XSTRNCPY(ctx->name, path, pathLen + 1);
             ctx->name[pathLen] = '\\';
             XSTRNCPY(ctx->name + pathLen + 1,
                      ctx->FindFileData.cFileName,
@@ -304,7 +304,7 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
             ret = BAD_PATH_ERROR;
             break;
         }
-        XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+        XSTRNCPY(ctx->name, path, pathLen + 1);
         ctx->name[pathLen] = '/';
         XSTRNCPY(ctx->name + pathLen + 1,
                  ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1);
@@ -350,7 +350,7 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
             if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
                 return BAD_PATH_ERROR;
             }
-            XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+            XSTRNCPY(ctx->name, path, pathLen + 1);
             ctx->name[pathLen] = '\\';
             XSTRNCPY(ctx->name + pathLen + 1,
                      ctx->FindFileData.cFileName,
@@ -368,7 +368,7 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
             ret = BAD_PATH_ERROR;
             break;
         }
-        XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ);
+        XSTRNCPY(ctx->name, path, pathLen + 1);
         ctx->name[pathLen] = '/';
         XSTRNCPY(ctx->name + pathLen + 1,
                  ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1);