From c805ff0601053c64e2a4feea5105d9c06ac0106c Mon Sep 17 00:00:00 2001 From: Mark Atwood Date: Thu, 9 Jul 2026 16:22:14 -0700 Subject: [PATCH] fix: guard sshd chroot steps after a failure SetupChroot() in wolfsshd ran chdir(chrootPath), chroot(chrootPath) and chdir("/") in three independent if-blocks with a single return at the end. Each ran unconditionally, so chroot() executed even when the preceding chdir() into the target failed. That can leave the process chrooted with a working directory still outside the new root. Short-circuit the later steps on the ret>0 (no-failure) state so chroot() runs only after the chdir() into the target succeeds, and chdir("/") only after chroot() succeeds. WS_FATAL_ERROR is negative, so ret>0 is true only while no step has failed. --- apps/wolfsshd/wolfsshd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/wolfsshd/wolfsshd.c b/apps/wolfsshd/wolfsshd.c index 71e6396cf..33d5bc26a 100644 --- a/apps/wolfsshd/wolfsshd.c +++ b/apps/wolfsshd/wolfsshd.c @@ -559,12 +559,16 @@ static int SetupChroot(WOLFSSHD_CONFIG* usrConf) "[SSHD] chdir to chroot path failed, %s", chrootPath); ret = WS_FATAL_ERROR; } - if (chroot(chrootPath) != 0) { + /* Only chroot() once the chdir() into the target succeeded, and only + * chdir("/") once inside the new root. Running a later step after an + * earlier failure could leave the process chrooted with a working + * directory outside the new root. */ + if (ret == 1 && chroot(chrootPath) != 0) { wolfSSH_Log(WS_LOG_ERROR, "[SSHD] chroot failed to path %s", chrootPath); ret = WS_FATAL_ERROR; } - if (chdir("/") != 0) { + if (ret == 1 && chdir("/") != 0) { wolfSSH_Log(WS_LOG_ERROR, "[SSHD] chdir after chroot failed"); ret = WS_FATAL_ERROR;