- Add user mode buffer probing for NtCreateKey, NtEnumerateKey, NtEnumerateValueKey, NtQueryKey, NtQueryValueKey

svn path=/trunk/; revision=41839
This commit is contained in:
Dmitry Chapyshev 2009-07-10 10:02:37 +00:00
parent 4af59e7e33
commit 312cc46636

View file

@ -23,9 +23,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex, IN ULONG TitleIndex,
IN PUNICODE_STRING Class, IN PUNICODE_STRING Class OPTIONAL,
IN ULONG CreateOptions, IN ULONG CreateOptions,
OUT PULONG Disposition) OUT PULONG Disposition OPTIONAL)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
@ -58,6 +58,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ProbeForRead(ObjectAttributes, ProbeForRead(ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES), sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG)); sizeof(ULONG));
if (Disposition) ProbeForWriteUlong(Disposition);
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -228,6 +230,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
IN ULONG Length, IN ULONG Length,
OUT PULONG ResultLength) OUT PULONG ResultLength)
{ {
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status; NTSTATUS Status;
PCM_KEY_BODY KeyObject; PCM_KEY_BODY KeyObject;
REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo; REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
@ -254,6 +257,29 @@ NtEnumerateKey(IN HANDLE KeyHandle,
NULL); NULL);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
if (PreviousMode != KernelMode)
{
_SEH2_TRY
{
ProbeForWriteUlong(ResultLength);
ProbeForWrite(KeyInformation,
Length,
sizeof(ULONG));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
/* Dereference and return status */
ObDereferenceObject(KeyObject);
return Status;
}
}
/* Setup the callback */ /* Setup the callback */
PostOperationInfo.Object = (PVOID)KeyObject; PostOperationInfo.Object = (PVOID)KeyObject;
EnumerateKeyInfo.Object = (PVOID)KeyObject; EnumerateKeyInfo.Object = (PVOID)KeyObject;
@ -293,6 +319,7 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
IN ULONG Length, IN ULONG Length,
OUT PULONG ResultLength) OUT PULONG ResultLength)
{ {
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status; NTSTATUS Status;
PCM_KEY_BODY KeyObject; PCM_KEY_BODY KeyObject;
REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo; REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo;
@ -319,6 +346,29 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
NULL); NULL);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
if (PreviousMode != KernelMode)
{
_SEH2_TRY
{
ProbeForWriteUlong(ResultLength);
ProbeForWrite(KeyValueInformation,
Length,
sizeof(ULONG));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
/* Dereference and return status */
ObDereferenceObject(KeyObject);
return Status;
}
}
/* Setup the callback */ /* Setup the callback */
PostOperationInfo.Object = (PVOID)KeyObject; PostOperationInfo.Object = (PVOID)KeyObject;
EnumerateValueKeyInfo.Object = (PVOID)KeyObject; EnumerateValueKeyInfo.Object = (PVOID)KeyObject;
@ -358,6 +408,7 @@ NtQueryKey(IN HANDLE KeyHandle,
IN ULONG Length, IN ULONG Length,
OUT PULONG ResultLength) OUT PULONG ResultLength)
{ {
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status; NTSTATUS Status;
PCM_KEY_BODY KeyObject; PCM_KEY_BODY KeyObject;
REG_QUERY_KEY_INFORMATION QueryKeyInfo; REG_QUERY_KEY_INFORMATION QueryKeyInfo;
@ -414,6 +465,29 @@ NtQueryKey(IN HANDLE KeyHandle,
/* Quit on failure */ /* Quit on failure */
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
if (PreviousMode != KernelMode)
{
_SEH2_TRY
{
ProbeForWriteUlong(ResultLength);
ProbeForWrite(KeyInformation,
Length,
sizeof(ULONG));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
/* Dereference and return status */
ObDereferenceObject(KeyObject);
return Status;
}
}
/* Setup the callback */ /* Setup the callback */
PostOperationInfo.Object = (PVOID)KeyObject; PostOperationInfo.Object = (PVOID)KeyObject;
QueryKeyInfo.Object = (PVOID)KeyObject; QueryKeyInfo.Object = (PVOID)KeyObject;
@ -452,6 +526,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
IN ULONG Length, IN ULONG Length,
OUT PULONG ResultLength) OUT PULONG ResultLength)
{ {
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status; NTSTATUS Status;
PCM_KEY_BODY KeyObject; PCM_KEY_BODY KeyObject;
REG_QUERY_VALUE_KEY_INFORMATION QueryValueKeyInfo; REG_QUERY_VALUE_KEY_INFORMATION QueryValueKeyInfo;
@ -470,6 +545,29 @@ NtQueryValueKey(IN HANDLE KeyHandle,
NULL); NULL);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
if (PreviousMode != KernelMode)
{
_SEH2_TRY
{
ProbeForWriteUlong(ResultLength);
ProbeForWrite(KeyValueInformation,
Length,
sizeof(ULONG));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
/* Dereference and return status */
ObDereferenceObject(KeyObject);
return Status;
}
}
/* Make sure the name is aligned properly */ /* Make sure the name is aligned properly */
if ((ValueNameCopy.Length & (sizeof(WCHAR) - 1))) if ((ValueNameCopy.Length & (sizeof(WCHAR) - 1)))
{ {