[KERNEL32]: BaseNamedObjectDirectory should work on demand, instead of on startup. Also, support cases when the thread is doing impersonation, to make sure it uses its real session ID and security access. Also, support cases when the BNO directory is not available, and use the BNO\Restricted directory instead (we should have our CSRSS create it).

svn path=/trunk/; revision=54286
This commit is contained in:
Alex Ionescu 2011-11-03 07:00:48 +00:00
parent 4ba4fdcb2c
commit 549dd7a686
6 changed files with 91 additions and 31 deletions

View file

@ -31,7 +31,6 @@ WCHAR BaseDefaultPathBuffer[6140];
HANDLE BaseNamedObjectDirectory; HANDLE BaseNamedObjectDirectory;
HMODULE hCurrentModule = NULL; HMODULE hCurrentModule = NULL;
HMODULE kernel32_handle = NULL; HMODULE kernel32_handle = NULL;
HANDLE hBaseDir = NULL;
PPEB Peb; PPEB Peb;
ULONG SessionId; ULONG SessionId;
BOOL ConsoleInitialized = FALSE; BOOL ConsoleInitialized = FALSE;
@ -288,15 +287,6 @@ DllMain(HANDLE hDll,
/* Initialize command line */ /* Initialize command line */
InitCommandLines(); InitCommandLines();
/* Open object base directory */
Status = BaseGetNamedObjectDirectory();
hBaseDir = BaseNamedObjectDirectory;
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open object base directory (Status %lx)\n", Status);
return FALSE;
}
/* Initialize the DLL critical section */ /* Initialize the DLL critical section */
RtlInitializeCriticalSection(&BaseDllDirectoryLock); RtlInitializeCriticalSection(&BaseDllDirectoryLock);

View file

@ -312,7 +312,7 @@ OpenFileMappingW(DWORD dwDesiredAccess,
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName, &UnicodeName,
(bInheritHandle ? OBJ_INHERIT : 0), (bInheritHandle ? OBJ_INHERIT : 0),
hBaseDir, BaseGetNamedObjectDirectory(),
NULL); NULL);
/* Convert COPY to READ */ /* Convert COPY to READ */

View file

@ -41,7 +41,7 @@ CreateMemoryResourceNotification(IN MEMORY_RESOURCE_NOTIFICATION_TYPE Notificati
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&EventName, &EventName,
0, 0,
hBaseDir, BaseGetNamedObjectDirectory(),
NULL); NULL);
Status = NtOpenEvent(&hEvent, Status = NtOpenEvent(&hEvent,

View file

@ -22,15 +22,46 @@
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
PRTL_CONVERT_STRING Basep8BitStringToUnicodeString; PRTL_CONVERT_STRING Basep8BitStringToUnicodeString;
UNICODE_STRING Restricted = RTL_CONSTANT_STRING(L"Restricted");
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
NTSTATUS HANDLE
WINAPI WINAPI
BaseGetNamedObjectDirectory(VOID) BaseGetNamedObjectDirectory(VOID)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status; NTSTATUS Status;
HANDLE DirHandle, BnoHandle, Token, NewToken;
if (BaseNamedObjectDirectory) return BaseNamedObjectDirectory;
if (NtCurrentTeb()->IsImpersonating)
{
Status = NtOpenThreadToken(NtCurrentThread(),
TOKEN_IMPERSONATE,
TRUE,
&Token);
if (!NT_SUCCESS(Status)) return BaseNamedObjectDirectory;
NewToken = NULL;
Status = NtSetInformationThread(NtCurrentThread(),
ThreadImpersonationToken,
&NewToken,
sizeof(HANDLE));
if (!NT_SUCCESS (Status))
{
NtClose(Token);
return BaseNamedObjectDirectory;
}
}
else
{
Token = NULL;
}
RtlAcquirePebLock();
if (BaseNamedObjectDirectory) goto Quickie;
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&BaseStaticServerData->NamedObjectDirectory, &BaseStaticServerData->NamedObjectDirectory,
@ -38,14 +69,54 @@ BaseGetNamedObjectDirectory(VOID)
NULL, NULL,
NULL); NULL);
Status = NtOpenDirectoryObject(&BaseNamedObjectDirectory, Status = NtOpenDirectoryObject(&BnoHandle,
DIRECTORY_ALL_ACCESS & DIRECTORY_QUERY |
~(DELETE | WRITE_DAC | WRITE_OWNER), DIRECTORY_TRAVERSE |
DIRECTORY_CREATE_OBJECT |
DIRECTORY_CREATE_SUBDIRECTORY,
&ObjectAttributes); &ObjectAttributes);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status))
{
Status = NtOpenDirectoryObject(&DirHandle,
DIRECTORY_TRAVERSE,
&ObjectAttributes);
DPRINT("Opened BNO: %lx\n", BaseNamedObjectDirectory); if (NT_SUCCESS(Status))
return Status; {
InitializeObjectAttributes(&ObjectAttributes,
(PUNICODE_STRING)&Restricted,
OBJ_CASE_INSENSITIVE,
DirHandle,
NULL);
Status = NtOpenDirectoryObject(&BnoHandle,
DIRECTORY_QUERY |
DIRECTORY_TRAVERSE |
DIRECTORY_CREATE_OBJECT |
DIRECTORY_CREATE_SUBDIRECTORY,
&ObjectAttributes);
NtClose(DirHandle);
}
}
if (NT_SUCCESS(Status)) BaseNamedObjectDirectory = BnoHandle;
Quickie:
RtlReleasePebLock();
if (Token)
{
NtSetInformationThread(NtCurrentThread(),
ThreadImpersonationToken,
&Token,
sizeof(Token));
NtClose(Token);
}
return BaseNamedObjectDirectory;
} }
VOID VOID
@ -224,7 +295,7 @@ BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes,
if (ObjectName) if (ObjectName)
{ {
Attributes |= OBJ_OPENIF; Attributes |= OBJ_OPENIF;
RootDirectory = hBaseDir; RootDirectory = BaseGetNamedObjectDirectory();
} }
else else
{ {
@ -282,10 +353,10 @@ BaseCreateStack(HANDLE hProcess,
{ {
StackReserve = ROUND_UP(StackCommit, 1024 * 1024); StackReserve = ROUND_UP(StackCommit, 1024 * 1024);
} }
StackCommit = ROUND_UP(StackCommit, PageSize); StackCommit = ROUND_UP(StackCommit, PageSize);
StackReserve = ROUND_UP(StackReserve, AllocationGranularity); StackReserve = ROUND_UP(StackReserve, AllocationGranularity);
GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes; GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes;
if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit)) if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit))
{ {
@ -299,7 +370,7 @@ BaseCreateStack(HANDLE hProcess,
StackCommit = ROUND_UP(StackCommit, PageSize); StackCommit = ROUND_UP(StackCommit, PageSize);
StackReserve = ROUND_UP(StackReserve, AllocationGranularity); StackReserve = ROUND_UP(StackReserve, AllocationGranularity);
/* ROS Hack until we support guard page stack expansion */ /* ROS Hack until we support guard page stack expansion */
StackCommit = StackReserve; StackCommit = StackReserve;
@ -337,7 +408,7 @@ BaseCreateStack(HANDLE hProcess,
{ {
UseGuard = FALSE; UseGuard = FALSE;
} }
/* Allocate memory for the stack */ /* Allocate memory for the stack */
Status = ZwAllocateVirtualMemory(hProcess, Status = ZwAllocateVirtualMemory(hProcess,
(PVOID*)&Stack, (PVOID*)&Stack,

View file

@ -100,7 +100,7 @@
POBJECT_ATTRIBUTES ObjectAttributes = &LocalAttributes; POBJECT_ATTRIBUTES ObjectAttributes = &LocalAttributes;
#define CreateNtObjectFromWin32ApiBody(ntobj, sec, name, access, ...) \ #define CreateNtObjectFromWin32ApiBody(ntobj, sec, name, access, ...) \
if (name) RtlInitUnicodeString(&ObjectName, name); \ if (name) RtlInitUnicodeString(&ObjectName, name); \
ObjectAttributes = BaseFormatObjectAttributes(&LocalAttributes, \ ObjectAttributes = BaseFormatObjectAttributes(&LocalAttributes, \
sec, \ sec, \
name ? &ObjectName : NULL); \ name ? &ObjectName : NULL); \
Status = NtCreate##ntobj(&Handle, access, ObjectAttributes, ##__VA_ARGS__); Status = NtCreate##ntobj(&Handle, access, ObjectAttributes, ##__VA_ARGS__);
@ -113,7 +113,7 @@
SetLastError(ERROR_SUCCESS); \ SetLastError(ERROR_SUCCESS); \
return Handle; \ return Handle; \
} \ } \
BaseSetLastNTError(Status); \ BaseSetLastNTError(Status); \
return NULL; \ return NULL; \
} }
@ -138,19 +138,19 @@
CreateNtObjectFromWin32ApiPrologue \ CreateNtObjectFromWin32ApiPrologue \
if (!name) \ if (!name) \
{ \ { \
BaseSetLastNTError(STATUS_INVALID_PARAMETER); \ BaseSetLastNTError(STATUS_INVALID_PARAMETER); \
return NULL; \ return NULL; \
} \ } \
RtlInitUnicodeString(&ObjectName, name); \ RtlInitUnicodeString(&ObjectName, name); \
InitializeObjectAttributes(ObjectAttributes, \ InitializeObjectAttributes(ObjectAttributes, \
&ObjectName, \ &ObjectName, \
inh ? OBJ_INHERIT : 0, \ inh ? OBJ_INHERIT : 0, \
hBaseDir, \ BaseGetNamedObjectDirectory(), \
NULL); \ NULL); \
Status = NtOpen##ntobj(&Handle, acc, ObjectAttributes); \ Status = NtOpen##ntobj(&Handle, acc, ObjectAttributes); \
if (!NT_SUCCESS(Status)) \ if (!NT_SUCCESS(Status)) \
{ \ { \
BaseSetLastNTError(Status); \ BaseSetLastNTError(Status); \
return NULL; \ return NULL; \
} \ } \
return Handle; \ return Handle; \

View file

@ -109,7 +109,6 @@ extern WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
/* GLOBAL VARIABLES **********************************************************/ /* GLOBAL VARIABLES **********************************************************/
extern BOOL bIsFileApiAnsi; extern BOOL bIsFileApiAnsi;
extern HANDLE hBaseDir;
extern HMODULE hCurrentModule; extern HMODULE hCurrentModule;
extern RTL_CRITICAL_SECTION BaseDllDirectoryLock; extern RTL_CRITICAL_SECTION BaseDllDirectoryLock;
@ -243,7 +242,7 @@ typedef NTSTATUS (NTAPI *PRTL_CONVERT_STRING)(IN PUNICODE_STRING UnicodeString,
extern PRTL_CONVERT_STRING Basep8BitStringToUnicodeString; extern PRTL_CONVERT_STRING Basep8BitStringToUnicodeString;
extern HANDLE BaseNamedObjectDirectory; extern HANDLE BaseNamedObjectDirectory;
NTSTATUS HANDLE
WINAPI WINAPI
BaseGetNamedObjectDirectory(VOID); BaseGetNamedObjectDirectory(VOID);