[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

svn path=/trunk/; revision=57429
This commit is contained in:
Timo Kreuzer
2012-09-29 13:22:31 +00:00
parent d28c6f3c65
commit 2cfa9a0af4
4 changed files with 131 additions and 138 deletions
+38 -32
View File
@@ -107,50 +107,56 @@ NtAddAtom(IN PWSTR AtomName,
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)
/* Check if we're called from user-mode or kernel-mode */
if (PreviousMode == KernelMode)
{
/* Enter SEH */
_SEH2_TRY
/* Re-use the given name if kernel mode */
CapturedName = AtomName;
}
else
{
/* Check if we have a name */
if (AtomName)
{
/* 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)
else
{
/* Return the exception code */
_SEH2_YIELD(return _SEH2_GetExceptionCode());
/* No name */
CapturedName = NULL;
}
_SEH2_END;
}
/* Call the runtime function */
@@ -172,7 +178,7 @@ NtAddAtom(IN PWSTR AtomName,
}
/* 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 @@ NtFindAtom(IN PWSTR AtomName,
DPRINT1("Atom name too long\n");
return STATUS_INVALID_PARAMETER;
}
/* Re-use the given name if kernel mode or no atom name */
CapturedName = AtomName;
+16 -8
View File
@@ -523,7 +523,7 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
ULONG SafeResponse;
UNICODE_STRING SafeString;
ULONG i;
ULONG ParamSize;
ULONG ParamSize = 0;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
/* Validate parameter count */
@@ -534,7 +534,7 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
}
/* 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 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
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,14 +585,8 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
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);
+10 -3
View File
@@ -349,9 +349,13 @@ NTSTATUS
NTAPI
NtQueryDefaultUILanguage(OUT LANGID* LanguageId)
{
NTSTATUS Status = STATUS_SUCCESS;
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 @@ NtQueryDefaultUILanguage(OUT LANGID* LanguageId)
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;
}
}
+67 -95
View File
@@ -211,27 +211,22 @@ NtQuerySystemEnvironmentValue(IN PUNICODE_STRING VariableName,
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 @@ NtQuerySystemEnvironmentValue(IN PUNICODE_STRING VariableName,
_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))
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;
}
return Status;
}
/*
* convert the value name to ansi
*/
Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE);
/*
* 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;
}
if (!NT_SUCCESS(Status)) return Status;
/* 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;
/*
* 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,
AnsiValueBuffer);
/*
* 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!
*/
/* 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 @@ ExQueryPoolUsage(OUT PULONG PagedPoolPages,
OUT PULONG NonPagedPoolAllocs,
OUT PULONG NonPagedPoolFrees,
OUT PULONG NonPagedPoolLookasideHits);
/* Class 0 - Basic Information */
QSI_DEF(SystemBasicInformation)
{
@@ -741,7 +713,7 @@ QSI_DEF(SystemProcessInformation)
do
{
SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
if ((Process->ProcessExiting) &&
(Process->Pcb.Header.SignalState) &&
!(Process->ActiveThreads) &&
@@ -1801,9 +1773,9 @@ SSI_DEF(SystemCreateSession)
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 @@ SSI_DEF(SystemCreateSession)
return STATUS_PRIVILEGE_NOT_HELD;
}
}
Status = MmSessionCreate(&SessionId);
if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId;
@@ -1824,9 +1796,9 @@ SSI_DEF(SystemDeleteSession)
{
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 @@ SSI_DEF(SystemDeleteSession)
return STATUS_PRIVILEGE_NOT_HELD;
}
}
SessionId = *(PULONG)Buffer;
return MmSessionDelete(SessionId);
}