/*********************************************************************** * CreateWindowStationA (USER32.@) */ HWINSTA WINAPI CreateWindowStationA( LPCSTR name, DWORD reserved, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa ) { WCHAR buffer[MAX_PATH]; if (!name) return CreateWindowStationW( NULL, reserved, access, sa ); if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } return CreateWindowStationW( buffer, reserved, access, sa ); }
/* good1() uses the GoodSinkBody in the for statements */ static void good1() { int k; for(k = 0; k < 1; k++) { { HWINSTA hWinStation; wchar_t * wStationName = L"WindowsStationExample"; /* FIX: Call CreateWindowStationW() without GENERIC_READ as the 3rd parameter to limit access */ hWinStation = CreateWindowStationW( wStationName, 0, GENERIC_READ, NULL); if (hWinStation == NULL) { printLine("Windows station could not be created"); } else { printLine("Windows Station created successfully"); CloseWindowStation(hWinStation); } } } }
/* * @implemented */ HWINSTA WINAPI CreateWindowStationA(LPCSTR lpwinsta, DWORD dwReserved, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa) { UNICODE_STRING WindowStationNameU; HWINSTA hWinSta; if (lpwinsta) { /* After conversion, the buffer is zero-terminated */ RtlCreateUnicodeStringFromAsciiz(&WindowStationNameU, lpwinsta); } else { RtlInitUnicodeString(&WindowStationNameU, NULL); } hWinSta = CreateWindowStationW(WindowStationNameU.Buffer, dwReserved, dwDesiredAccess, lpsa); /* Free the string, if it was allocated */ if (lpwinsta) RtlFreeUnicodeString(&WindowStationNameU); return hWinSta; }
void CWE284_Improper_Access_Control__w32_wchar_t_CreateWindowStation_17_bad() { int j; for(j = 0; j < 1; j++) { { HWINSTA hWinStation; wchar_t * wStationName = L"WindowsStationExample"; /* FLAW: Call CreateWindowStationW() with GENERIC_ALL as the 3rd parameter */ hWinStation = CreateWindowStationW( wStationName, 0, GENERIC_ALL, NULL); if (hWinStation == NULL) { printLine("Windows station could not be created"); } else { printLine("Windows Station created successfully"); CloseWindowStation(hWinStation); } } } }
/* good1() uses if(5!=5) instead of if(5==5) */ static void good1() { if(5!=5) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { { HWINSTA hWinStation; wchar_t * wStationName = L"WindowsStationExample"; /* FIX: Call CreateWindowStationW() without GENERIC_READ as the 3rd parameter to limit access */ hWinStation = CreateWindowStationW( wStationName, 0, GENERIC_READ, NULL); if (hWinStation == NULL) { printLine("Windows station could not be created"); } else { printLine("Windows Station created successfully"); CloseWindowStation(hWinStation); } } } }
/* * This test inspects the same window station aspects that are used in the * Cygwin fhandler_console.cc!fhandler_console::create_invisible_console() * function, see: * https://github.com/cygwin/cygwin/blob/7b9bfb4136f23655e243bab89fb62b04bdbacc7f/winsup/cygwin/fhandler_console.cc#L2494 */ VOID DoTest(HWND hWnd) { HWINSTA hWinSta; LPCWSTR lpszWinSta = L"Test-WinSta"; BOOL bIsItOk; LOG_FILE LogFile; WCHAR szBuffer[2048]; bIsItOk = InitLog(&LogFile, L"test_winsta.log", szBuffer, sizeof(szBuffer)); if (!bIsItOk) { MessageBoxW(hWnd, L"Could not create the log file, stopping test now...", L"Error", MB_ICONERROR | MB_OK); return; } /* Switch output to UTF-16 (little endian) */ WriteToLog(&LogFile, "\xFF\xFE", 2); WriteToLogPrintf(&LogFile, L"Creating Window Station '%s'\r\n", lpszWinSta); hWinSta = CreateWindowStationW(lpszWinSta, 0, WINSTA_ALL_ACCESS, NULL); WriteToLogPrintf(&LogFile, L"--> Returned handle 0x%p ; last error: %lu\r\n", hWinSta, GetLastError()); if (!hWinSta) { WriteToLogPuts(&LogFile, L"\r\nHandle is NULL, cannot proceed further, stopping the test!\r\n\r\n"); return; } WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (before process attach)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Setting current process to Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = SetProcessWindowStation(hWinSta); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after process attach, before allocating console)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Allocating a new console on Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = AllocConsole(); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after allocating console)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Now closing Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = CloseWindowStation(hWinSta); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); CloseLog(&LogFile); }
HWINSTA CreateInheritableWinsta(WCHAR* name, ACCESS_MASK dwDesiredAccess, BOOL inheritable) { SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = inheritable; return CreateWindowStationW(name, 0, dwDesiredAccess, &sa ); }
void Test_OpenInputDesktop() { HDESK hDeskInput ,hDeskInput2; HDESK hDeskInitial; BOOL ret; HWINSTA hwinsta = NULL, hwinstaInitial; DWORD err; hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(hDeskInput != NULL, "OpenInputDesktop failed\n"); hDeskInitial = GetThreadDesktop( GetCurrentThreadId() ); ok(hDeskInitial != NULL, "GetThreadDesktop failed\n"); ok(hDeskInput != hDeskInitial, "OpenInputDesktop returned thread desktop\n"); hDeskInput2 = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(hDeskInput2 != NULL, "Second call to OpenInputDesktop failed\n"); ok(hDeskInput2 != hDeskInput, "Second call to OpenInputDesktop returned same handle\n"); ok(CloseDesktop(hDeskInput2) != 0, "CloseDesktop failed\n"); ret = SetThreadDesktop(hDeskInput); ok(ret == TRUE, "SetThreadDesktop for input desktop failed\n"); ret = SetThreadDesktop(hDeskInitial); ok(ret == TRUE, "SetThreadDesktop for initial desktop failed\n"); ok(CloseDesktop(hDeskInput) != 0, "CloseDesktop failed\n"); /* Try calling OpenInputDesktop after switching to a new winsta */ hwinstaInitial = GetProcessWindowStation(); ok(hwinstaInitial != 0, "GetProcessWindowStation failed\n"); hwinsta = CreateWindowStationW(L"TestWinsta", 0, WINSTA_ALL_ACCESS, NULL); ok(hwinsta != 0, "CreateWindowStationW failed\n"); ret = SetProcessWindowStation(hwinsta); ok(ret != 0, "SetProcessWindowStation failed\n"); hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(hDeskInput == 0, "OpenInputDesktop should fail\n"); err = GetLastError(); ok(err == ERROR_INVALID_FUNCTION, "Got last error: %lu\n", err); ret = SetProcessWindowStation(hwinstaInitial); ok(ret != 0, "SetProcessWindowStation failed\n"); ret = CloseWindowStation(hwinsta); ok(ret != 0, "CloseWindowStation failed\n"); }
// this is required when we're replacing winlogon void init_window_station( void ) { SECURITY_ATTRIBUTES sa; HANDLE hwsta, hdesk; sa.nLength = sizeof sa; sa.lpSecurityDescriptor = 0; sa.bInheritHandle = TRUE; hwsta = CreateWindowStationW( L"winsta0", 0, MAXIMUM_ALLOWED, &sa ); SetProcessWindowStation( hwsta ); hdesk = CreateDesktopW( L"Winlogon", 0, 0, 0, MAXIMUM_ALLOWED, &sa ); SetThreadDesktop( hdesk ); }
/*********************************************************************** * winstation_init * * Connect to the process window station and desktop. */ static void winstation_init(void) { static const WCHAR WinSta0[] = {'W','i','n','S','t','a','0',0}; STARTUPINFOW info; WCHAR *winstation = NULL, *desktop = NULL, *buffer = NULL; HANDLE handle; GetStartupInfoW( &info ); if (info.lpDesktop && *info.lpDesktop) { buffer = HeapAlloc( GetProcessHeap(), 0, (strlenW(info.lpDesktop) + 1) * sizeof(WCHAR) ); strcpyW( buffer, info.lpDesktop ); if ((desktop = strchrW( buffer, '\\' ))) { *desktop++ = 0; winstation = buffer; } else desktop = buffer; } /* set winstation if explicitly specified, or if we don't have one yet */ if (buffer || !GetProcessWindowStation()) { handle = CreateWindowStationW( winstation ? winstation : WinSta0, 0, WINSTA_ALL_ACCESS, NULL ); if (handle) { SetProcessWindowStation( handle ); /* only WinSta0 is visible */ if (!winstation || !strcmpiW( winstation, WinSta0 )) { USEROBJECTFLAGS flags; flags.fInherit = FALSE; flags.fReserved = FALSE; flags.dwFlags = WSF_VISIBLE; SetUserObjectInformationW( handle, UOI_FLAGS, &flags, sizeof(flags) ); } } } if (buffer || !GetThreadDesktop( GetCurrentThreadId() )) { handle = CreateDesktopW( desktop ? desktop : get_default_desktop(), NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); if (handle) SetThreadDesktop( handle ); } HeapFree( GetProcessHeap(), 0, buffer ); }
BOOL CreateWindowStationAndDesktops( IN OUT PWLSESSION Session) { BYTE LocalSystemBuffer[SECURITY_MAX_SID_SIZE]; BYTE InteractiveBuffer[SECURITY_MAX_SID_SIZE]; PSID pLocalSystemSid = (PSID)&LocalSystemBuffer; PSID pInteractiveSid = (PSID)InteractiveBuffer; DWORD SidSize, AclSize; PACL pDefaultAcl = NULL; PACL pUserDesktopAcl = NULL; SECURITY_DESCRIPTOR DefaultSecurityDescriptor; SECURITY_ATTRIBUTES DefaultSecurity; SECURITY_DESCRIPTOR UserDesktopSecurityDescriptor; SECURITY_ATTRIBUTES UserDesktopSecurity; BOOL ret = FALSE; /* * Prepare information for ACLs we will apply */ SidSize = SECURITY_MAX_SID_SIZE; if (!CreateWellKnownSid(WinLocalSystemSid, NULL, pLocalSystemSid, &SidSize)) { ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); goto cleanup; } SidSize = SECURITY_MAX_SID_SIZE; if (!CreateWellKnownSid(WinInteractiveSid, NULL, pInteractiveSid, &SidSize)) { ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); goto cleanup; } AclSize = sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pLocalSystemSid) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pInteractiveSid); pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); pUserDesktopAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); if (!pDefaultAcl || !pUserDesktopAcl) { ERR("WL: HeapAlloc() failed\n"); goto cleanup; } if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION) || !InitializeAcl(pUserDesktopAcl, AclSize, ACL_REVISION)) { ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create default ACL (window station, winlogon desktop, screen saver desktop) */ if (!AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid) || !AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_READ, pInteractiveSid)) { ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create the default security descriptor */ if (!InitializeSecurityDescriptor(&DefaultSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); goto cleanup; } if (!SetSecurityDescriptorDacl(&DefaultSecurityDescriptor, TRUE, pDefaultAcl, FALSE)) { ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); goto cleanup; } DefaultSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); DefaultSecurity.lpSecurityDescriptor = &DefaultSecurityDescriptor; DefaultSecurity.bInheritHandle = TRUE; /* * Create user desktop ACL */ if (!AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid) || !AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pInteractiveSid)) { ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create the user desktop security descriptor */ if (!InitializeSecurityDescriptor(&UserDesktopSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); goto cleanup; } if (!SetSecurityDescriptorDacl(&UserDesktopSecurityDescriptor, TRUE, pUserDesktopAcl, FALSE)) { ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); goto cleanup; } UserDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); UserDesktopSecurity.lpSecurityDescriptor = &UserDesktopSecurityDescriptor; UserDesktopSecurity.bInheritHandle = TRUE; /* * Create the interactive window station */ Session->InteractiveWindowStationName = L"WinSta0"; Session->InteractiveWindowStation = CreateWindowStationW( Session->InteractiveWindowStationName, 0, MAXIMUM_ALLOWED, &DefaultSecurity); if (!Session->InteractiveWindowStation) { ERR("WL: Failed to create window station (%lu)\n", GetLastError()); goto cleanup; } if (!SetProcessWindowStation(Session->InteractiveWindowStation)) { ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create the application desktop */ Session->ApplicationDesktop = CreateDesktopW( L"Default", NULL, NULL, 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */ MAXIMUM_ALLOWED, &UserDesktopSecurity); if (!Session->ApplicationDesktop) { ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError()); goto cleanup; } /* * Create the winlogon desktop */ Session->WinlogonDesktop = CreateDesktopW( L"Winlogon", NULL, NULL, 0, MAXIMUM_ALLOWED, &DefaultSecurity); if (!Session->WinlogonDesktop) { ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError()); goto cleanup; } /* * Create the screen saver desktop */ Session->ScreenSaverDesktop = CreateDesktopW( L"Screen-Saver", NULL, NULL, 0, MAXIMUM_ALLOWED, &DefaultSecurity); if(!Session->ScreenSaverDesktop) { ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError()); goto cleanup; } /* * Switch to winlogon desktop */ if (!SetThreadDesktop(Session->WinlogonDesktop) || !SwitchDesktop(Session->WinlogonDesktop)) { ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError()); goto cleanup; } ret = TRUE; cleanup: if (!ret) { if (Session->ApplicationDesktop) { CloseDesktop(Session->ApplicationDesktop); Session->ApplicationDesktop = NULL; } if (Session->WinlogonDesktop) { CloseDesktop(Session->WinlogonDesktop); Session->WinlogonDesktop = NULL; } if (Session->ScreenSaverDesktop) { CloseDesktop(Session->ScreenSaverDesktop); Session->ScreenSaverDesktop = NULL; } if (Session->InteractiveWindowStation) { CloseWindowStation(Session->InteractiveWindowStation); Session->InteractiveWindowStation = NULL; } } HeapFree(GetProcessHeap(), 0, pDefaultAcl); HeapFree(GetProcessHeap(), 0, pUserDesktopAcl); return ret; }