From 0615ca79a4d91fdbc6949458d80973f6b8a6ed6c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 29 Jul 2026 09:00:17 -0700 Subject: [PATCH 1/2] Fix DEADCODE defect in CheckAlgoList() - noneOk was only ever set inside the WOLFSSH_ALLOW_NONE_CIPHER guard, so usableCount++ was unreachable in the default build. - Move the whole ID_NONE arm under the guard and drop noneOk. Behavior is unchanged in both builds. Issues: CID-651702 --- src/internal.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/internal.c b/src/internal.c index b53b4aeb2..ea50fb4a9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3113,20 +3113,18 @@ int CheckAlgoList(const char* list, byte type) byte id = NameToIdType(name, nameSz, &tokenType); if (id == ID_NONE) { - int noneOk = 0; - /* "none" names the null cipher/MAC, not a host key. It * disables the transport, so it needs the build flag. */ #ifdef WOLFSSH_ALLOW_NONE_CIPHER - if (type == TYPE_CIPHER || type == TYPE_MAC) { - noneOk = 1; - } -#endif - if (!noneOk) { + if (type != TYPE_CIPHER && type != TYPE_MAC) { ret = WS_INVALID_ALGO_ID; break; } usableCount++; +#else + ret = WS_INVALID_ALGO_ID; + break; +#endif } else if (id != ID_UNKNOWN) { /* Wrong category is a caller mistake, not a build From f658bdeccb3b063ca9d6b936ab1e60e81e2b9ff9 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 29 Jul 2026 09:00:17 -0700 Subject: [PATCH 2/2] Fix TOCTOU defect in test_ConfigSavePID() - Scenarios 1 and 5 fopen() once and fstat() that handle instead of stat()ing the path a second time. - A failed open is now a logged error rather than an indirect rd == 0. - The FIFO lstat() and failPath existence test stay as they are: neither has a descriptor to stat, and mkdtemp()'s 0700 directory makes them unraceable. Issues: CID-651701 --- apps/wolfsshd/test/test_configuration.c | 32 +++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/apps/wolfsshd/test/test_configuration.c b/apps/wolfsshd/test/test_configuration.c index 3f795a53f..4b52a1cd9 100644 --- a/apps/wolfsshd/test/test_configuration.c +++ b/apps/wolfsshd/test/test_configuration.c @@ -2747,6 +2747,9 @@ static int test_ConfigSavePID(void) void (*prevXfsz)(int); #endif + /* Every path below lives in this directory, which mkdtemp() creates mode + * 0700. No other user can traverse it, so none of the path-based checks + * here can be raced. */ if (mkdtemp(base) == NULL) { Log(" mkdtemp failed.\n"); ret = WS_FATAL_ERROR; @@ -2773,15 +2776,16 @@ static int test_ConfigSavePID(void) ret = pidSave(conf, pidPath); } if (ret == WS_SUCCESS) { - if (stat(pidPath, &st) != 0) { + /* fstat() the open handle instead of stat()ing the path a second + * time, so the mode asserted below belongs to the same file the PID + * was read from. */ + f = fopen(pidPath, "r"); + if (f == NULL || fstat(fileno(f), &st) != 0) { + Log(" Could not open or stat %s.\n", pidPath); ret = WS_FATAL_ERROR; } else { - f = fopen(pidPath, "r"); - rd = (f != NULL) ? fscanf(f, "%ld", &pid) : 0; - if (f != NULL) { - fclose(f); - } + rd = fscanf(f, "%ld", &pid); ret = smExpect("normal PID file written with our PID", (rd == 1 && pid == (long)getpid()) ? WS_SUCCESS : WS_FATAL_ERROR, 1); @@ -2791,6 +2795,9 @@ static int test_ConfigSavePID(void) : WS_SUCCESS, 1); } } + if (f != NULL) { + fclose(f); + } } /* Scenario 2: a symlink at the PID path is refused, link target untouched. @@ -2897,15 +2904,13 @@ static int test_ConfigSavePID(void) } if (ret == WS_SUCCESS) { pid = -1; - if (stat(stale, &st) != 0) { + f = fopen(stale, "r"); + if (f == NULL || fstat(fileno(f), &st) != 0) { + Log(" Could not open or stat %s.\n", stale); ret = WS_FATAL_ERROR; } else { - f = fopen(stale, "r"); - rd = (f != NULL) ? fscanf(f, "%ld", &pid) : 0; - if (f != NULL) { - fclose(f); - } + rd = fscanf(f, "%ld", &pid); ret = smExpect("existing PID file rewritten with our PID", (rd == 1 && pid == (long)getpid()) ? WS_SUCCESS : WS_FATAL_ERROR, 1); @@ -2916,6 +2921,9 @@ static int test_ConfigSavePID(void) : WS_SUCCESS, 1); } } + if (f != NULL) { + fclose(f); + } } /* Scenario 6: a PID file owned by another user is refused instead of being