wslc: prevent session name squatting for default WSLc sessions#40144
wslc: prevent session name squatting for default WSLc sessions#40144benhillis merged 2 commits intofeature/wsl-for-appsfrom
Conversation
There was a problem hiding this comment.
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;
}
6df494e to
c991c9d
Compare
c991c9d to
46d783e
Compare
46c11a9 to
7cb7ef9
Compare
7cb7ef9 to
784b41f
Compare
784b41f to
d0b3819
Compare
There was a problem hiding this comment.
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 nowWSLCUserSettings.cpp. Please update the module name to match the actual filename to avoid confusion when tracing build/log output and code ownership.
d0b3819 to
50b93fb
Compare
50b93fb to
bfd1cae
Compare
There was a problem hiding this comment.
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/service/exe/WSLCSessionManager.h:80
CreateSessionandOpenSessionByNamenow acceptnullptrfor default-session resolution (per the updated IDL), but the corresponding declarations here still use_In_for the pointer parameters. Please update the SAL annotations to_In_opt_(and similarly markWslcSessionSettingsas optional) so static analysis and code readers match the new contract.
void GetVersion(_Out_ WSLCVersion* Version);
void CreateSession(const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWSLCSession** WslcSession);
void EnterSession(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWSLCSession** WslcSession);
void ListSessions(_Out_ WSLCSessionInformation** Sessions, _Out_ ULONG* SessionsCount);
void OpenSession(_In_ ULONG Id, _Out_ IWSLCSession** Session);
void OpenSessionByName(_In_ LPCWSTR DisplayName, _Out_ IWSLCSession** Session);
dkbennett
left a comment
There was a problem hiding this comment.
All the session changes as they relate to the CLI look good to me. Minor comments about having more specific error codes for better diagnosability. We can always add this later but would be easier to pay as we go.
2043b98 to
cbc897e
Compare
- 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 case-insensitive E_ACCESSDENIED check - Null StoragePath remains valid for ephemeral sessions; empty string is rejected as E_INVALIDARG - Add dedicated EnterSession API with null/empty parameter validation - Early return optimization: skip YAML parse if default session exists - Inline BuildFeatureFlags into SessionSettings constructor - Extract UserSettings into shared wslcsettings library used by both wslc.exe and wslservice.exe - Move EnumVariantMap.h to common - 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 with case-insensitive coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rsonation - Append username to default session names so different users don't collide (e.g. wslc-cli-alice, wslc-cli-admin-bob) [OneBlue] - Impersonate caller when loading settings.yaml server-side [OneBlue] - Factor name resolution into ResolveDefaultSessionName helper [OneBlue] - Add WSLC_E_SESSION_RESERVED and WSLC_E_INVALID_SESSION_NAME error codes for better diagnosability [dkbennett] - Use prefix-based reserved name check (blocks all wslc-cli-* names) - Fix pre-existing HostFileShareMode namespace qualification bug - Remove unused variable in GetDefaultStoragePath test helper [Copilot] - Update all E2E tests for username-qualified session names Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
cbc897e to
8d63613
Compare
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
CreateSession(nullptr)andOpenSessionByName(nullptr)resolve the default session name from the caller's token and username (e.g.wslc-cli-alice,wslc-cli-admin-bob). The client no longer knows or sends session names for default sessions.CreateSessionreturnsWSLC_E_SESSION_RESERVED. Invalid session names returnWSLC_E_INVALID_SESSION_NAME.wil::impersonate_token.EnterSessionAPI: Custom sessions (wslc session enter) use a separate API that readssettings.yamlserver-side and setsNoCreatestorage flags.wslcsettingsshared library: ExtractedUserSettingsinto a shared library used by bothwslc.exeandwslservice.exe.SettingsCommandnow callsUserSettingsdirectly instead of duplicating file creation logic.SessionOptionsclass,SessionModel.cpp,WslcSettingsTemplate.h. MovedEnumVariantMap.hto common.SessionSettingsisNON_MOVABLE(usesunique_ptrto avoidc_str()pointer invalidation).Testing