The named shared memory segment used to pass pipe handles to the
desktop-server child process is created with a NULL DACL - any local
account can open and read it.
DesktopServerWatcher::execute() (desktop/DesktopServerWatcher.cpp)
generates a name "Global\<20 chars>" seeded with srand(time(0)) -
one-second granularity, trivially predictable. Real Windows pipe HANDLEs
for the parent-child IPC channel are written to mem[1]-mem[6].
SharedMemory::setAllAccess() (win-system/SharedMemory.cpp:111) calls
SetSecurityInfo with lpDacl=NULL. Comment confirms: "Pointer to DACL
(0 = access to all)". The segment is in the Global\ namespace visible
to all sessions.
Any local unprivileged process can: (1) brute-force or enumerate the name,
(2) read the pipe HANDLEs, (3) overwrite them before the ready flag is set.
Attached PoC proves cross-process read: subprocess OpenFileMappingW
succeeds and reads the canary value without any elevated privileges.
Fix: BCryptGenRandom for the name; restrictive DACL.
Version: 2.8.87.