Author: jmorlan Date: Fri Jun 4 08:36:12 2010 New Revision: 47562
URL: http://svn.reactos.org/svn/reactos?rev=47562&view=rev Log: [KERNEL32], [WIN32CSR] - Make Get/SetConsoleTitle more compatible with windows; in particular, transfer title via capture buffer to allow for longer titles. - Tighten up capture buffer validation in win32csr.
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c trunk/reactos/include/reactos/subsys/csrss/csrss.h trunk/reactos/subsystems/win32/csrss/win32csr/alias.c trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c trunk/reactos/subsystems/win32/csrss/win32csr/conoutput.c trunk/reactos/subsystems/win32/csrss/win32csr/console.c trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/con... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -3418,6 +3418,64 @@ }
+static DWORD +IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode) +{ + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE); + NTSTATUS Status; + + if (nSize == 0) + return 0; + + Request.Data.GetTitleRequest.Length = nSize * (bUnicode ? 1 : sizeof(WCHAR)); + CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.GetTitleRequest.Length); + if (CaptureBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + CsrAllocateMessagePointer(CaptureBuffer, + Request.Data.GetTitleRequest.Length, + (PVOID*)&Request.Data.GetTitleRequest.Title); + + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status))) + { + CsrFreeCaptureBuffer(CaptureBuffer); + SetLastErrorByStatus(Status); + return 0; + } + + if (bUnicode) + { + if (nSize >= sizeof(WCHAR)) + wcscpy((LPWSTR)lpConsoleTitle, Request.Data.GetTitleRequest.Title); + } + else + { + if (nSize < Request.Data.GetTitleRequest.Length / sizeof(WCHAR) || + !WideCharToMultiByte(CP_ACP, // ANSI code page + 0, // performance and mapping flags + Request.Data.GetTitleRequest.Title, // address of wide-character string + -1, // number of characters in string + (LPSTR)lpConsoleTitle, // address of buffer for new string + nSize, // size of buffer + NULL, // FAST + NULL)) + { + /* Yes, if the buffer isn't big enough, it returns 0... Bad API */ + *(LPSTR)lpConsoleTitle = '\0'; + Request.Data.GetTitleRequest.Length = 0; + } + } + CsrFreeCaptureBuffer(CaptureBuffer); + + return Request.Data.GetTitleRequest.Length / sizeof(WCHAR); +} + /*-------------------------------------------------------------- * GetConsoleTitleW * @@ -3428,48 +3486,8 @@ GetConsoleTitleW(LPWSTR lpConsoleTitle, DWORD nSize) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); - if (Request == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE); - - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); - if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status))) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - SetLastErrorByStatus(Status); - return 0; - } - - if (nSize * sizeof(WCHAR) <= Request->Data.GetTitleRequest.Length) - { - nSize--; - } - else - { - nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR); - } - memcpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize * sizeof(WCHAR)); - lpConsoleTitle[nSize] = L'\0'; - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - - return nSize; -} - + return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE); +}
/*-------------------------------------------------------------- * GetConsoleTitleA @@ -3483,28 +3501,7 @@ GetConsoleTitleA(LPSTR lpConsoleTitle, DWORD nSize) { - WCHAR WideTitle [CSRSS_MAX_TITLE_LENGTH + 1]; - DWORD nWideTitle = CSRSS_MAX_TITLE_LENGTH + 1; - DWORD nWritten; - - if (!lpConsoleTitle || !nSize) return 0; - nWideTitle = GetConsoleTitleW((LPWSTR) WideTitle, nWideTitle); - if (!nWideTitle) return 0; - - if ((nWritten = WideCharToMultiByte(CP_ACP, // ANSI code page - 0, // performance and mapping flags - (LPWSTR) WideTitle, // address of wide-character string - nWideTitle, // number of characters in string - lpConsoleTitle, // address of buffer for new string - nSize - 1, // size of buffer - NULL, // FAST - NULL))) // FAST - { - lpConsoleTitle[nWritten] = '\0'; - return nWritten; - } - - return 0; + return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE); }
@@ -3517,40 +3514,32 @@ WINAPI SetConsoleTitleW(LPCWSTR lpConsoleTitle) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - unsigned int c; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + - min(wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR))); - if (Request == NULL) + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); + NTSTATUS Status; + + Request.Data.SetTitleRequest.Length = wcslen(lpConsoleTitle) * sizeof(WCHAR); + + CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.SetTitleRequest.Length); + if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; }
- CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); - - for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++) - Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; - - Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR); - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); + CsrCaptureMessageBuffer(CaptureBuffer, + (PVOID)lpConsoleTitle, + Request.Data.SetTitleRequest.Length, + (PVOID*)&Request.Data.SetTitleRequest.Title); + + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { SetLastErrorByStatus(Status); - return(FALSE); - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); + return FALSE; + }
return TRUE; } @@ -3567,43 +3556,18 @@ WINAPI SetConsoleTitleA(LPCSTR lpConsoleTitle) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - unsigned int c; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + - min(strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR))); - if (Request == NULL) + ULONG Length = strlen(lpConsoleTitle) + 1; + LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR)); + BOOL Ret; + if (!WideTitle) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - - CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); - - for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++) - Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; - - Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR); - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - SetLastErrorByStatus(Status); - return(FALSE); - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - - return TRUE; + MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length); + Ret = SetConsoleTitleW(WideTitle); + HeapFree(GetProcessHeap(), 0, WideTitle); + return Ret; }
Modified: trunk/reactos/include/reactos/subsys/csrss/csrss.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/csrs... ============================================================================== --- trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -207,13 +207,13 @@ typedef struct { DWORD Length; - WCHAR Title[0]; + PWCHAR Title; } CSRSS_SET_TITLE, *PCSRSS_SET_TITLE;
typedef struct { DWORD Length; - WCHAR Title[0]; + PWCHAR Title; } CSRSS_GET_TITLE, *PCSRSS_GET_TITLE;
typedef struct @@ -487,11 +487,6 @@ #define CSRSS_MAX_READ_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)) #define CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)) #define CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)) -#define CSRSS_MAX_GET_PROCESS_LIST (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)) - -/* WCHARs, not bytes! */ -#define CSRSS_MAX_TITLE_LENGTH 80 -#define CSRSS_MAX_ALIAS_TARGET_LENGTH 80
#define CREATE_PROCESS (0x0) #define TERMINATE_PROCESS (0x1)
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/alias.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/alias.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/alias.c [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -31,21 +31,6 @@
} ALIAS_HEADER, *PALIAS_HEADER;
-/* Ensure that a buffer is contained within the process's shared memory section. */ -static BOOL -ValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, PVOID Buffer, ULONG Size) -{ - ULONG Offset = (BYTE *)Buffer - (BYTE *)ProcessData->CsrSectionViewBase; - if (Offset >= ProcessData->CsrSectionViewSize - || Size > (ProcessData->CsrSectionViewSize - Offset)) - { - DPRINT1("Invalid buffer %p %d; not within %p %d\n", - Buffer, Size, ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); - return FALSE; - } - return TRUE; -} - static PALIAS_HEADER IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName) @@ -415,7 +400,8 @@ return STATUS_BUFFER_TOO_SMALL; }
- if (!ValidateBuffer(ProcessData, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength)) + if (!Win32CsrValidateBuffer(ProcessData, lpTarget, + Request->Data.GetConsoleAlias.TargetBufferLength, 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; @@ -457,9 +443,10 @@ return STATUS_BUFFER_OVERFLOW; }
- if (!ValidateBuffer(ProcessData, - Request->Data.GetAllConsoleAlias.AliasBuffer, - Request->Data.GetAllConsoleAlias.AliasBufferLength)) + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetAllConsoleAlias.AliasBuffer, + Request->Data.GetAllConsoleAlias.AliasBufferLength, + 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; @@ -532,9 +519,10 @@ return STATUS_INVALID_PARAMETER; }
- if (!ValidateBuffer(ProcessData, - Request->Data.GetConsoleAliasesExes.ExeNames, - Request->Data.GetConsoleAliasesExes.Length)) + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetConsoleAliasesExes.ExeNames, + Request->Data.GetConsoleAliasesExes.Length, + 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION;
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -678,7 +678,6 @@ { NTSTATUS Status; PCSRSS_CONSOLE Console; - DWORD Size; DWORD Length; PLIST_ENTRY CurrentItem; PINPUT_RECORD InputRecord; @@ -698,10 +697,8 @@
InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; Length = Request->Data.PeekConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + + if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD))) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; @@ -749,7 +746,6 @@ PCSRSS_CONSOLE Console; NTSTATUS Status; DWORD Length; - DWORD Size; DWORD i; ConsoleInput* Record;
@@ -766,10 +762,8 @@
InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; Length = Request->Data.WriteConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + + if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD))) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION;
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conoutput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/conoutput.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/conoutput.c [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -1084,7 +1084,6 @@ COORD BufferSize; NTSTATUS Status; PBYTE Ptr; - DWORD PSize;
DPRINT("CsrWriteConsoleOutput\n");
@@ -1101,12 +1100,10 @@ Console = Buff->Header.Console;
BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; - PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) || - (((ULONG_PTR)CharInfo + PSize) > - ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (!Win32CsrValidateBuffer(ProcessData, CharInfo, + BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) { ConioUnlockScreenBuffer(Buff); return STATUS_ACCESS_VIOLATION; @@ -1395,8 +1392,6 @@ PCHAR_INFO CharInfo; PCHAR_INFO CurCharInfo; PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - DWORD Length; DWORD SizeX, SizeY; NTSTATUS Status; COORD BufferSize; @@ -1423,14 +1418,12 @@ ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; - Length = BufferSize.X * BufferSize.Y; - Size = Length * sizeof(CHAR_INFO);
/* FIXME: Is this correct? */ CodePage = ProcessData->Console->OutputCodePage;
- if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + if (!Win32CsrValidateBuffer(ProcessData, CharInfo, + BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) { ConioUnlockScreenBuffer(Buff); return STATUS_ACCESS_VIOLATION;
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/console.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/console.c [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -455,19 +455,15 @@
DPRINT("CsrSetTitle\n");
- if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) - + Request->Data.SetTitleRequest.Length) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if (!Win32CsrValidateBuffer(ProcessData, Request->Data.SetTitleRequest.Title, + Request->Data.SetTitleRequest.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); if(NT_SUCCESS(Status)) { Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); @@ -507,6 +503,13 @@
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (!Win32CsrValidateBuffer(ProcessData, Request->Data.GetTitleRequest.Title, + Request->Data.GetTitleRequest.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + Status = ConioConsoleFromProcessData(ProcessData, &Console); if (! NT_SUCCESS(Status)) { @@ -515,19 +518,16 @@ }
/* Copy title of the console to the user title buffer */ - RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); + if (Request->Data.GetTitleRequest.Length >= sizeof(WCHAR)) + { + Length = min(Request->Data.GetTitleRequest.Length - sizeof(WCHAR), Console->Title.Length); + memcpy(Request->Data.GetTitleRequest.Title, Console->Title.Buffer, Length); + Request->Data.GetTitleRequest.Title[Length / sizeof(WCHAR)] = L'\0'; + } + Request->Data.GetTitleRequest.Length = Console->Title.Length; - memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, - Console->Title.Length); - Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length; - - ConioUnlockConsole(Console); - - if (Length > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Length; - Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); - } + + ConioUnlockConsole(Console); return STATUS_SUCCESS; }
@@ -754,7 +754,6 @@ PLIST_ENTRY current_entry; ULONG nItems = 0; NTSTATUS Status; - ULONG_PTR Offset;
DPRINT("CsrGetProcessList\n");
@@ -762,13 +761,8 @@ Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Buffer = Request->Data.GetProcessListRequest.ProcessId; - Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase; - if (Offset >= ProcessData->CsrSectionViewSize - || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset) - || Offset & (sizeof(DWORD) - 1)) - { + if (!Win32CsrValidateBuffer(ProcessData, Buffer, Request->Data.GetProcessListRequest.nMaxIds, sizeof(DWORD))) return STATUS_ACCESS_VIOLATION; - }
Status = ConioConsoleFromProcessData(ProcessData, &Console); if (! NT_SUCCESS(Status))
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -100,6 +100,32 @@ return TRUE; }
+/* Ensure that a captured buffer is safe to access */ +BOOL FASTCALL +Win32CsrValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, PVOID Buffer, + SIZE_T NumElements, SIZE_T ElementSize) +{ + /* Check that the following conditions are true: + * 1. The start of the buffer is somewhere within the process's + * shared memory section view. + * 2. The remaining space in the view is at least as large as the buffer. + * (NB: Please don't try to "optimize" this by using multiplication + * instead of division; remember that 2147483648 * 2 = 0.) + * 3. The buffer is DWORD-aligned. + */ + ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->CsrSectionViewBase; + if (Offset >= ProcessData->CsrSectionViewSize + || NumElements > (ProcessData->CsrSectionViewSize - Offset) / ElementSize + || (Offset & (sizeof(DWORD) - 1)) != 0) + { + DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n", + Buffer, NumElements, ElementSize, + ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); + return FALSE; + } + return TRUE; +} + NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context)
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h [iso-8859-1] Fri Jun 4 08:36:12 2010 @@ -63,6 +63,10 @@ CSR_API(CsrDuplicateHandle); CSR_API(CsrGetInputWaitHandle);
+BOOL FASTCALL Win32CsrValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, + PVOID Buffer, + SIZE_T NumElements, + SIZE_T ElementSize); NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context);