Author: tkreuzer Date: Sat Sep 29 13:22:31 2012 New Revision: 57429
URL: http://svn.reactos.org/svn/reactos?rev=57429&view=rev Log: [NTOSKRNL] - Allocate a capture buffer outside of SEH in NtAddAtom and NtRaiseHardError - Call ExpGetCurrentUserUILanguage outside of SEH in NtQueryDefaultUILanguage and return the actual result instead of returning PsInstallUILanguageId in case of success. - Don't allocate a unicode string inside SEH in NtQuerySystemEnvironmentValue, instead use RtlAnsiStringToUnicodeString directly on the callers buffer. CORE-6624
Modified: trunk/reactos/ntoskrnl/ex/atom.c trunk/reactos/ntoskrnl/ex/harderr.c trunk/reactos/ntoskrnl/ex/locale.c trunk/reactos/ntoskrnl/ex/sysinfo.c
Modified: trunk/reactos/ntoskrnl/ex/atom.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/atom.c?rev=5742... ============================================================================== --- trunk/reactos/ntoskrnl/ex/atom.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ex/atom.c [iso-8859-1] Sat Sep 29 13:22:31 2012 @@ -107,50 +107,56 @@ DPRINT1("Atom name too long\n"); return STATUS_INVALID_PARAMETER; } - - /* Re-use the given name if kernel mode or no atom name */ - CapturedName = AtomName; - - /* Check if we're called from user-mode*/ - if (PreviousMode != KernelMode) - { - /* Enter SEH */ - _SEH2_TRY - { - /* Check if we have a name */ - if (AtomName) + + /* Check if we're called from user-mode or kernel-mode */ + if (PreviousMode == KernelMode) + { + /* Re-use the given name if kernel mode */ + CapturedName = AtomName; + } + else + { + /* Check if we have a name */ + if (AtomName) + { + /* Allocate an aligned buffer + the null char */ + CapturedSize = ((AtomNameLength + sizeof(WCHAR)) & + ~(sizeof(WCHAR) -1)); + CapturedName = ExAllocatePoolWithTag(PagedPool, + CapturedSize, + TAG_ATOM); + + if (!CapturedName) + { + /* Fail the call */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Enter SEH */ + _SEH2_TRY { /* Probe the atom */ ProbeForRead(AtomName, AtomNameLength, sizeof(WCHAR));
- /* Allocate an aligned buffer + the null char */ - CapturedSize = ((AtomNameLength + sizeof(WCHAR)) &~ - (sizeof(WCHAR) -1)); - CapturedName = ExAllocatePoolWithTag(PagedPool, - CapturedSize, - TAG_ATOM); - if (!CapturedName) - { - /* Fail the call */ - Status = STATUS_INSUFFICIENT_RESOURCES; - } - else - { - /* Copy the name and null-terminate it */ - RtlCopyMemory(CapturedName, AtomName, AtomNameLength); - CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL; - } + /* Copy the name and null-terminate it */ + RtlCopyMemory(CapturedName, AtomName, AtomNameLength); + CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL;
/* Probe the atom too */ if (Atom) ProbeForWriteUshort(Atom); } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + /* No name */ + CapturedName = NULL; + } }
/* Call the runtime function */ @@ -172,7 +178,7 @@ }
/* If we captured anything, free it */ - if ((CapturedName) && (CapturedName != AtomName)) + if ((CapturedName != NULL) && (CapturedName != AtomName)) ExFreePoolWithTag(CapturedName, TAG_ATOM);
/* Return to caller */ @@ -258,7 +264,7 @@ DPRINT1("Atom name too long\n"); return STATUS_INVALID_PARAMETER; } - + /* Re-use the given name if kernel mode or no atom name */ CapturedName = AtomName;
Modified: trunk/reactos/ntoskrnl/ex/harderr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/harderr.c?rev=5... ============================================================================== --- trunk/reactos/ntoskrnl/ex/harderr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ex/harderr.c [iso-8859-1] Sat Sep 29 13:22:31 2012 @@ -523,7 +523,7 @@ ULONG SafeResponse; UNICODE_STRING SafeString; ULONG i; - ULONG ParamSize; + ULONG ParamSize = 0; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
/* Validate parameter count */ @@ -534,7 +534,7 @@ }
/* Make sure we have some at least */ - if ((Parameters) && !(NumberOfParameters)) + if ((Parameters != NULL) && (NumberOfParameters == 0)) { /* Fail */ return STATUS_INVALID_PARAMETER_2; @@ -561,6 +561,20 @@ return STATUS_INVALID_PARAMETER_4; }
+ /* Check if we have parameters */ + if (Parameters) + { + /* Calculate size of the parameters */ + ParamSize = sizeof(ULONG_PTR) * NumberOfParameters; + + /* Allocate a safe buffer */ + SafeParams = ExAllocatePoolWithTag(PagedPool, ParamSize, TAG_ERR); + if (!SafeParams) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + } + /* Enter SEH Block */ _SEH2_TRY { @@ -571,13 +585,7 @@ if (Parameters) { /* Validate the parameter pointers */ - ParamSize = sizeof(ULONG_PTR) * NumberOfParameters; ProbeForRead(Parameters, ParamSize, sizeof(ULONG_PTR)); - - /* Allocate a safe buffer */ - SafeParams = ExAllocatePoolWithTag(PagedPool, - ParamSize, - TAG_ERR);
/* Copy them */ RtlCopyMemory(SafeParams, Parameters, ParamSize);
Modified: trunk/reactos/ntoskrnl/ex/locale.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/locale.c?rev=57... ============================================================================== --- trunk/reactos/ntoskrnl/ex/locale.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ex/locale.c [iso-8859-1] Sat Sep 29 13:22:31 2012 @@ -349,8 +349,12 @@ NTAPI NtQueryDefaultUILanguage(OUT LANGID* LanguageId) { - NTSTATUS Status = STATUS_SUCCESS; - PAGED_CODE(); + NTSTATUS Status; + LANGID SafeLanguageId; + PAGED_CODE(); + + /* Call the executive helper routine */ + Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", &SafeLanguageId);
/* Enter SEH for probing */ _SEH2_TRY @@ -362,11 +366,14 @@ ProbeForWriteLangid(LanguageId); }
- /* Call the executive helper routine */ - Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", LanguageId); if (NT_SUCCESS(Status)) { /* Success, return the language */ + *LanguageId = SafeLanguageId; + } + else + { + /* Failed, use fallback value */ *LanguageId = PsInstallUILanguageId; } }
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=5... ============================================================================== --- trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] Sat Sep 29 13:22:31 2012 @@ -211,27 +211,22 @@ ANSI_STRING AName; UNICODE_STRING WName; ARC_STATUS Result; - PCH Value; + PCH AnsiValueBuffer; ANSI_STRING AValue; UNICODE_STRING WValue; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; PAGED_CODE();
+ /* Check if the call came from user mode */ PreviousMode = ExGetPreviousMode(); - if (PreviousMode != KernelMode) { _SEH2_TRY { - ProbeForRead(VariableName, - sizeof(UNICODE_STRING), - sizeof(ULONG)); - - ProbeForWrite(ValueBuffer, - ValueBufferLength, - sizeof(WCHAR)); - + /* Probe the input and output buffers */ + ProbeForRead(VariableName, sizeof(UNICODE_STRING), sizeof(ULONG)); + ProbeForWrite(ValueBuffer, ValueBufferLength, sizeof(WCHAR)); if (ReturnLength != NULL) ProbeForWriteUlong(ReturnLength); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -240,102 +235,79 @@ _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; + + } + + /* Allocate a buffer for the value */ + AnsiValueBuffer = ExAllocatePoolWithTag(NonPagedPool, ValueBufferLength, 'pmeT'); + if (AnsiValueBuffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; }
/* * Copy the name to kernel space if necessary and convert it to ANSI. */ - Status = ProbeAndCaptureUnicodeString(&WName, - PreviousMode, - VariableName); - if (NT_SUCCESS(Status)) - { - /* - * according to ntinternals the SeSystemEnvironmentName privilege is required! - */ - if (!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege, - PreviousMode)) - { - ReleaseCapturedUnicodeString(&WName, PreviousMode); - DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n"); - return STATUS_PRIVILEGE_NOT_HELD; - } - - /* - * convert the value name to ansi - */ - Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE); + Status = ProbeAndCaptureUnicodeString(&WName, PreviousMode, VariableName); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* + * according to ntinternals the SeSystemEnvironmentName privilege is required! + */ + if (!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege, PreviousMode)) + { ReleaseCapturedUnicodeString(&WName, PreviousMode); - - if (!NT_SUCCESS(Status)) return Status; - - /* - * Create a temporary buffer for the value - */ - Value = ExAllocatePool(NonPagedPool, ValueBufferLength); - if (Value == NULL) - { - RtlFreeAnsiString(&AName); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* - * Get the environment variable - */ - Result = HalGetEnvironmentVariable(AName.Buffer, - (USHORT)ValueBufferLength, - Value); - if (!Result) - { - RtlFreeAnsiString(&AName); - ExFreePool(Value); - return STATUS_UNSUCCESSFUL; - } - - /* - * Convert the result to UNICODE, protect with SEH in case the value buffer - * isn't NULL-terminated! - */ + DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n"); + return STATUS_PRIVILEGE_NOT_HELD; + } + + /* Convert the value name to ansi and release the captured unicode string */ + Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE); + ReleaseCapturedUnicodeString(&WName, PreviousMode); + if (!NT_SUCCESS(Status)) return Status; + + /* Get the environment variable */ + Result = HalGetEnvironmentVariable(AName.Buffer, + (USHORT)ValueBufferLength, + AnsiValueBuffer); + + /* Check if we had success */ + if (Result == ESUCCESS) + { + /* Copy the result back to the caller. */ _SEH2_TRY { - RtlInitAnsiString(&AValue, Value); - Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE); + /* Initialize ansi string from the result */ + RtlInitAnsiString(&AValue, AnsiValueBuffer); + + /* Initialize a unicode string from the callers buffer */ + RtlInitEmptyUnicodeString(&WValue, ValueBuffer, ValueBufferLength); + + /* Convert the result to unicode */ + Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, FALSE); + + if (ReturnLength != NULL) + { + *ReturnLength = WValue.Length; + } } _SEH2_EXCEPT(ExSystemExceptionFilter()) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; - - if (NT_SUCCESS(Status)) - { - /* - * Copy the result back to the caller. - */ - _SEH2_TRY - { - RtlCopyMemory(ValueBuffer, WValue.Buffer, WValue.Length); - ValueBuffer[WValue.Length / sizeof(WCHAR)] = L'\0'; - if (ReturnLength != NULL) - { - *ReturnLength = WValue.Length + sizeof(WCHAR); - } - - Status = STATUS_SUCCESS; - } - _SEH2_EXCEPT(ExSystemExceptionFilter()) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - - /* - * Cleanup allocated resources. - */ - RtlFreeAnsiString(&AName); - ExFreePool(Value); - } + } + else + { + Status = STATUS_UNSUCCESSFUL; + } + + /* Cleanup allocated resources. */ + RtlFreeAnsiString(&AName); + ExFreePoolWithTag(AnsiValueBuffer, 'pmeT');
return Status; } @@ -466,7 +438,7 @@ OUT PULONG NonPagedPoolAllocs, OUT PULONG NonPagedPoolFrees, OUT PULONG NonPagedPoolLookasideHits); - + /* Class 0 - Basic Information */ QSI_DEF(SystemBasicInformation) { @@ -741,7 +713,7 @@ do { SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current; - + if ((Process->ProcessExiting) && (Process->Pcb.Header.SignalState) && !(Process->ActiveThreads) && @@ -1801,9 +1773,9 @@ ULONG SessionId; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); NTSTATUS Status; - + if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH; - + if (PreviousMode != KernelMode) { if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode)) @@ -1811,7 +1783,7 @@ return STATUS_PRIVILEGE_NOT_HELD; } } - + Status = MmSessionCreate(&SessionId); if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId;
@@ -1824,9 +1796,9 @@ { ULONG SessionId; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); - + if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH; - + if (PreviousMode != KernelMode) { if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode)) @@ -1834,9 +1806,9 @@ return STATUS_PRIVILEGE_NOT_HELD; } } - + SessionId = *(PULONG)Buffer; - + return MmSessionDelete(SessionId); }