@samitouri / QOSAMI-WSL / commits / 61e6b9aa

Fix wsl stuck when misconfigured cifs mount presents (#14466)

* detach terminal before running mount -a * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * use _exit on error before execv in child process to avoid unintentional resource release * Add regression test * Fix clang format issue * fix all clang format issue * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * resolve ai comments * move test to unit test * Fix string literal * Overwrite fstab to resolve pipeline missing file issue --------- Co-authored-by: Feng Wang <wangfen@microsoft.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Feng Wang committed Mar 21, 2026 at 03:45 UTC 61e6b9aa8686b6a855070668455a163e83ec925c
4 files changed +45 -5
src/linux/init/config.cpp
+1 -1
@@ -2137,7 +2137,7 @@ Return Value:
2137 //
2138
2139 const char* const Argv[] = {MOUNT_COMMAND, MOUNT_FSTAB_ARG, nullptr};
2140 - if (UtilCreateProcessAndWait(Argv[0], Argv, nullptr, {{WSL_DRVFS_ELEVATED_ENV, Elevated ? "1" : "0"}}) < 0)
2140 + if (UtilCreateProcessAndWait(Argv[0], Argv, nullptr, {{WSL_DRVFS_ELEVATED_ENV, Elevated ? "1" : "0"}}, true) < 0)
2141 {
2142 auto message = wsl::shared::Localization::MessageFstabMountFailed();
2143 LOG_ERROR("{}", message.c_str());
src/linux/init/util.cpp
+19 -3
@@ -613,7 +613,7 @@ Return Value:
613 return SocketFd;
614 }
615
616 -int UtilCreateProcessAndWait(const char* const File, const char* const Argv[], int* Status, const std::map<std::string, std::string>& Env)
616 +int UtilCreateProcessAndWait(const char* const File, const char* const Argv[], int* Status, const std::map<std::string, std::string>& Env, bool DetachTerminal)
617
618 /*++
619
@@ -630,6 +630,9 @@ Arguments:
630 Status - Supplies an optional pointer that receives the exit status of the
631 process.
632
633 + DetachTerminal - Supplies a boolean that, when true, calls setsid() in the
634 + child process to detach it from the controlling terminal.
635 +
636 Return Value:
637
638 0 on success, -1 on failure.
@@ -664,7 +667,7 @@ Return Value:
667
668 if (UtilSetSignalHandlers(g_SavedSignalActions, false) < 0 || UtilRestoreBlockedSignals() < 0)
669 {
667 - exit(-1);
670 + _exit(-1);
671 }
672
673 //
@@ -676,6 +679,19 @@ Return Value:
679 setenv(e.first.c_str(), e.second.c_str(), 1);
680 }
681
682 + //
683 + // Detach from the controlling terminal if requested.
684 + //
685 +
686 + if (DetachTerminal)
687 + {
688 + if (setsid() == -1)
689 + {
690 + LOG_ERROR("setsid failed {}", errno);
691 + _exit(-1);
692 + }
693 + }
694 +
695 //
696 // Invoke the executable.
697 //
@@ -686,7 +702,7 @@ Return Value:
702 // with std::string anyway.
703 execv(File, const_cast<char* const*>(Argv));
704 LOG_ERROR("execv({}) failed with {}", File, errno);
689 - exit(-1);
705 + _exit(-1);
706 }
707
708 if (Status == nullptr)
src/linux/init/util.h
+2 -1
@@ -191,7 +191,8 @@ Return Value:
191 _exit(1);
192 }
193
194 -int UtilCreateProcessAndWait(const char* File, const char* const Argv[], int* Status = nullptr, const std::map<std::string, std::string>& Env = {});
194 +int UtilCreateProcessAndWait(
195 + const char* File, const char* const Argv[], int* Status = nullptr, const std::map<std::string, std::string>& Env = {}, bool DetachTerminal = false);
196
197 template <typename TMethod>
198 void UtilCreateWorkerThread(const char* Name, TMethod&& ThreadFunction)
test/windows/UnitTests.cpp
+23
@@ -6539,5 +6539,28 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
6539 VERIFY_ARE_EQUAL(err, L"");
6540 }
6541
6542 + TEST_METHOD(InteractiveMount)
6543 + {
6544 + WSL2_TEST_ONLY();
6545 +
6546 + // Add a fake interactive mount helper.
6547 + DistroFileChange mountHelper(L"/sbin/mount.hang", false);
6548 + mountHelper.SetContent(
6549 + L"#!/bin/sh\n"
6550 + L"read pass < /dev/tty\n");
6551 + VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"chmod +x /sbin/mount.hang"), (DWORD)0);
6552 +
6553 + // Don't keep the original fstab as it can be missing on the pipeline.
6554 + DistroFileChange fstab(L"/etc/fstab", false);
6555 + fstab.SetContent(L"none /mnt/ttytest hang 0 0\n");
6556 +
6557 + // Restart the distro with this mount.
6558 + WslShutdown();
6559 + wsl::windows::common::SubProcess process(nullptr, LxssGenerateWslCommandLine(L"echo booted").c_str());
6560 + auto result = process.RunAndCaptureOutput(60 * 1000);
6561 + VERIFY_ARE_EQUAL(result.Stdout, L"booted\n");
6562 + VERIFY_ARE_EQUAL(result.ExitCode, 0);
6563 + }
6564 +
6565 }; // namespace UnitTests
6566 } // namespace UnitTests