Just a good advice, which can possibly save many hours of debugging time.
Many drivers use SeSinglePrivilegeCheck to check whether the user is “admin
as defined by this driver”. This is simple and logical. For instance, if the
driver has something to do with disk, then the Backup privilege can be used as
the notion of “admin” for it (anyway Administrators have it). And so on.
In this case, AdjustTokenPrivileges is often used by the user-mode code
before opening the driver control file object or before calling some IOCTLs.
AdjustTokenPrivileges has the DisableAllPrivileges parameter. NOTE: it is
dangerous!
The thing is that if you will call AdjustTokenPrivileges with
DisableAllPrivileges = TRUE to reverse the things back after doing the
privileged operation, then you can step on a nasty issue, which occurs on XP
with Fast User Switching.
The issue is that, if:
- Win32 process have called AdjustTokenPrivileges with DisableAllPrivileges =
TRUE
AND - you’re running on XP with Fast User Switching
then this process will be unable to create the children by CreateProcess.
Any child wil fail with STATUS_DLL_INIT_FAILED.
Since calling the driver is often done from the shell extension, this
situation can easily lead to Explorer being unable to execute any child. Task
Manager will still be able, though.
So, your product can have the issue of “Sometimes Explorer cannot start any
EXE if running on XP with Fast User Switching and some operations on our
product were performed”.
The technical background is that the init routine of kernel32.dll calls
CsrClientConnectToServer to register the process in CSRSS, which calls
NtSecureConnectPort on \Windows\1\ApiPort in the kernel, which in turn fails
inside ObReferenceObjectByName due to lack of Traverse privilege.
So, looks like that Traverse privilege is now mandatory for Win32
(disabling it blocks the ability to start child processes, at least in some
setups). So, do not ever call AdjustTokenPrivileges with DisableAllPrivileges =
TRUE, even if David LeBlanc would advice so
The reason is that the normal state of token is not “all privileges off”,
it at least has Traverse privilege on. So, using DisableAllPrivileges = TRUE
just serves no purpose except breaking the important functions.
Please disable all privileges enabled by you “personally” by restoring
their old states returned by the first AdjustTokenPrivileges call.
–
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com