Skip to content

wslc: prevent session name squatting for default WSLc sessions#40144

Open
benhillis wants to merge 1 commit intofeature/wsl-for-appsfrom
user/benhill/wslc_default_session
Open

wslc: prevent session name squatting for default WSLc sessions#40144
benhillis wants to merge 1 commit intofeature/wsl-for-appsfrom
user/benhill/wslc_default_session

Conversation

@benhillis
Copy link
Copy Markdown
Member

Summary

Prevents malicious users from squatting reserved WSLc session names (wslc-cli, wslc-cli-admin) by moving default session name and settings resolution to the server.

Changes

  • Server-side default sessions: CreateSession(nullptr) and OpenSessionByName(nullptr) resolve the default session name from the caller's token. The client no longer knows or sends session names for default sessions.
  • Reserved name rejection: Explicit use of reserved names via CreateSession returns E_ACCESSDENIED.
  • Dedicated EnterSession API: Custom sessions (wslc session enter) use a separate API that reads settings.yaml server-side and sets NoCreate storage flags.
  • wslcsettings shared library: Extracted UserSettings into a shared library used by both wslc.exe and wslservice.exe. SettingsCommand now calls UserSettings directly instead of duplicating file creation logic.
  • Cleanup: Removed SessionOptions class, SessionModel.cpp, WslcSettingsTemplate.h. Moved EnumVariantMap.h to common. SessionSettings is NON_MOVABLE (uses unique_ptr to avoid c_str() pointer invalidation).

Testing

  • E2E test verifies reserved names are rejected and default session creation still works.
  • All 158 WSLCE2E tests pass (2 skipped).

Copilot AI review requested due to automatic review settings April 9, 2026 16:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@benhillis benhillis changed the base branch from master to feature/wsl-for-apps April 9, 2026 16:26
@benhillis benhillis requested a review from Copilot April 9, 2026 16:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 24 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/windows/wslc/services/SessionService.cpp:45

  • When attaching to the default session (empty sessionName -> nullptr passed to OpenSessionByName), failure paths still format errors using sessionName.c_str(), which is an empty string. This produces user-facing messages like "Session '' not found". Consider special-casing the empty-name/default-session case and emitting a clearer localized message (e.g., "Default session not found" / "Failed to open default session") instead of printing an empty name.
    HRESULT hr = manager->OpenSessionByName(sessionName.empty() ? nullptr : sessionName.c_str(), &session);
    if (FAILED(hr))
    {
        if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
        {
            wslutil::PrintMessage(Localization::MessageWslcSessionNotFound(sessionName.c_str()), stderr);
            return 1;
        }

        auto errorString = wsl::windows::common::wslutil::ErrorCodeToString(hr);
        wslutil::PrintMessage(
            Localization::MessageErrorCode(Localization::MessageWslcOpenSessionFailed(sessionName.c_str()), errorString), stderr);
        return 1;

src/windows/wslc/services/SessionService.cpp:186

  • TerminateSession now treats an empty displayName as "default session" (nullptr passed to OpenSessionByName), but the "not found" / "terminate failed" messages still use displayName.c_str() and can end up printing an empty name. Please special-case the default-session call path so the error message is meaningful when no session name was provided.
    wil::com_ptr<IWSLCSession> session;
    HRESULT hr = sessionManager->OpenSessionByName(displayName.empty() ? nullptr : displayName.c_str(), &session);
    if (FAILED(hr))
    {
        if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
        {
            wslutil::PrintMessage(Localization::MessageWslcSessionNotFound(displayName.c_str()), stderr);
            return 1;
        }

@benhillis benhillis force-pushed the user/benhill/wslc_default_session branch from 6df494e to c991c9d Compare April 9, 2026 22:50
Copilot AI review requested due to automatic review settings April 9, 2026 22:54
@benhillis benhillis force-pushed the user/benhill/wslc_default_session branch from c991c9d to 46d783e Compare April 9, 2026 22:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 25 changed files in this pull request and generated 1 comment.

@benhillis benhillis force-pushed the user/benhill/wslc_default_session branch 2 times, most recently from 46c11a9 to 7cb7ef9 Compare April 10, 2026 00:31
Copilot AI review requested due to automatic review settings April 10, 2026 00:31
@benhillis benhillis force-pushed the user/benhill/wslc_default_session branch from 7cb7ef9 to 784b41f Compare April 10, 2026 00:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 25 changed files in this pull request and generated 5 comments.

@benhillis benhillis force-pushed the user/benhill/wslc_default_session branch from 784b41f to d0b3819 Compare April 10, 2026 02:12
@benhillis benhillis changed the title Prevent session name squatting for default WSLc sessions wslc: prevent session name squatting for default WSLc sessions Apr 10, 2026
@benhillis benhillis marked this pull request as ready for review April 10, 2026 02:22
@benhillis benhillis requested a review from a team as a code owner April 10, 2026 02:22
Copilot AI review requested due to automatic review settings April 10, 2026 02:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 25 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/windows/common/WSLCUserSettings.cpp:12

  • File header comment still says Module Name: UserSettings.cpp, but the file is now WSLCUserSettings.cpp. Please update the module name to match the actual filename to avoid confusion when tracing build/log output and code ownership.

Comment on lines 144 to +176
@@ -88,6 +167,14 @@ void WSLCSessionManagerImpl::CreateSession(const WSLCSessionSettings* Settings,

wslutil::StopWatch stopWatch;

// Initialize settings for the default session.
std::unique_ptr<SessionSettings> defaultSettings;
if (Settings == nullptr)
{
defaultSettings = SessionSettings::Default(callerToken.get(), tokenInfo.Elevated);
Settings = &defaultSettings->Settings;
}
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateSession holds m_wslcSessionsLock while loading/parsing user settings (YAML) for default sessions (SessionSettings::Default(...)). This introduces file I/O and YAML parsing under the session manager lock, which can block other session operations and increase contention. Consider building the resolved/default SessionSettings outside the lock (or caching per-user settings) and only holding the lock for the session lookup/mutation portion.

Copilot uses AI. Check for mistakes.
Comment on lines +1938 to +1946
<data name="MessageWslcDefaultSessionNotFound" xml:space="preserve">
<value>Default session not found</value>
</data>
<data name="MessageWslcOpenDefaultSessionFailed" xml:space="preserve">
<value>Failed to open default session</value>
</data>
<data name="MessageWslcTerminateDefaultSessionFailed" xml:space="preserve">
<value>Default session termination failed</value>
</data>
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New user-facing resource keys were added only to en-US/Resources.resw. Other locales currently lack these entries (the localization validator only warns), which can cause missing translations/fallback-to-English behavior for non-en-US users. Consider adding placeholder entries for these keys in the other locale .resw files so localization can pick them up consistently.

Copilot uses AI. Check for mistakes.
- Server now determines default session name and settings from caller's
  token, preventing malicious users from squatting reserved session names
- CreateSession rejects explicit use of reserved names (wslc-cli,
  wslc-cli-admin) with E_ACCESSDENIED
- Null StoragePath remains valid for ephemeral sessions; empty string
  is rejected as E_INVALIDARG
- Add dedicated EnterSession API for custom sessions
- Extract UserSettings into shared wslcsettings library used by both
  wslc.exe and wslservice.exe
- Move EnumVariantMap.h to common
- wslc.exe no longer parses settings.yaml; service handles all config
- Fix std::terminate crash in CustomDmesgOutput test when CreateSession
  fails by adding a scope_exit guard to join the reader thread
- Add session name squatting E2E test
@benhillis benhillis force-pushed the user/benhill/wslc_default_session branch from d0b3819 to 50b93fb Compare April 10, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants