- Implement handle access checking on all console functions.

- OpenConsoleW: Fourth parameter is actually share mode (passing a number from 0 to 2 will usually give ERROR_SHARING_VIOLATION on Windows)
- CreateFileW: Move CONIN$/CONOUT$ handling after dwCreationDisposition checks (it must be valid, even though it doesn't matter which it is); pass FILE_SHARE_READ|FILE_SHARE_WRITE to OpenConsoleW (dwShareMode is ignored).
- CloseConsoleHandle, CsrReleaseObject, CsrVerifyObject: Remove IsConsoleHandle checks - Windows ignores lower 2 bits of handle for closing and verifying.
- SetConsoleMode: Remove IsConsoleHandle check - it's redundant, since the same check is done in CsrGetObject.
- CsrIsConsoleHandle, CsrReleaseObjectByPointer: Clean up a bit.
- CsrFreeConsole: Remove the process from the console's list.

svn path=/trunk/; revision=34694
This commit is contained in:
Jeffrey Morlan 2008-07-23 16:21:46 +00:00
parent dd1b21d54b
commit 4246bf6783
7 changed files with 62 additions and 71 deletions

View file

@ -104,16 +104,6 @@ HANDLE STDCALL CreateFileW (LPCWSTR lpFileName,
TRACE("CreateFileW(lpFileName %S)\n",lpFileName);
/* check for console input/output */
if (0 == _wcsicmp(L"CONOUT$", lpFileName)
|| 0 == _wcsicmp(L"CONIN$", lpFileName))
{
return OpenConsoleW(lpFileName,
dwDesiredAccess,
lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE,
dwCreationDisposition);
}
/* validate & translate the creation disposition */
switch (dwCreationDisposition)
{
@ -142,6 +132,16 @@ HANDLE STDCALL CreateFileW (LPCWSTR lpFileName,
return (INVALID_HANDLE_VALUE);
}
/* check for console input/output */
if (0 == _wcsicmp(L"CONOUT$", lpFileName)
|| 0 == _wcsicmp(L"CONIN$", lpFileName))
{
return OpenConsoleW(lpFileName,
dwDesiredAccess,
lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
}
/* validate & translate the flags */
/* translate the flags that need no validation */

View file

@ -906,7 +906,7 @@ HANDLE STDCALL
OpenConsoleW (LPCWSTR wsName,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwCreationDistribution)
DWORD dwShareMode)
/*
* Undocumented
*/
@ -933,7 +933,7 @@ OpenConsoleW (LPCWSTR wsName,
SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE);
}
if (OPEN_EXISTING != dwCreationDistribution)
if (dwShareMode & ~(FILE_SHARE_READ|FILE_SHARE_WRITE))
{
SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE);
@ -1261,12 +1261,6 @@ CloseConsoleHandle(HANDLE Handle)
NTSTATUS Status;
if (IsConsoleHandle (Handle) == FALSE)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
Request.Data.CloseHandleRequest.Handle = Handle;
Status = CsrClientCallServer(&Request,
@ -2907,14 +2901,6 @@ SetConsoleMode(
NTSTATUS Status;
if (!IsConsoleHandle (hConsoleHandle))
{
DPRINT("SetConsoleMode was called with a non console handle\n");
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
Request.Data.SetConsoleModeRequest.Mode = dwMode;

View file

@ -19,10 +19,10 @@
static unsigned ObjectDefinitionsCount = 0;
static PCSRSS_OBJECT_DEFINITION ObjectDefinitions = NULL;
BOOL
static BOOL
CsrIsConsoleHandle(HANDLE Handle)
{
return ((((ULONG)Handle) & 0x10000003) == 0x3) ? TRUE : FALSE;
return ((ULONG)Handle & 0x10000003) == 0x3;
}
@ -89,26 +89,21 @@ NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, O
NTSTATUS STDCALL
CsrReleaseObjectByPointer(Object_t *Object)
{
BOOL Found;
unsigned DefIndex;
/* dec ref count */
if (_InterlockedDecrement(&Object->ReferenceCount) == 0)
{
Found = FALSE;
for (DefIndex = 0; ! Found && DefIndex < ObjectDefinitionsCount; DefIndex++)
for (DefIndex = 0; DefIndex < ObjectDefinitionsCount; DefIndex++)
{
if (Object->Type == ObjectDefinitions[DefIndex].Type)
{
(ObjectDefinitions[DefIndex].CsrCleanupObjectProc)(Object);
Found = TRUE;
return STATUS_SUCCESS;
}
}
if (! Found)
{
DPRINT1("CSR: Error: releaseing unknown object type 0x%x", Object->Type);
}
DPRINT1("CSR: Error: releasing unknown object type 0x%x", Object->Type);
}
return STATUS_SUCCESS;
@ -127,7 +122,7 @@ CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
return STATUS_INVALID_PARAMETER;
}
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
if (h >= ProcessData->HandleTableSize
|| (Object = ProcessData->HandleTable[h].Object) == NULL)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
@ -234,7 +229,7 @@ NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle
{
return STATUS_INVALID_PARAMETER;
}
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
if (h >= ProcessData->HandleTableSize
|| ProcessData->HandleTable[h].Object == NULL)
{
return STATUS_INVALID_HANDLE;

View file

@ -152,12 +152,12 @@ CSR_API(CsrGetProcessList);
#define ConioRectWidth(Rect) \
(((Rect)->left) > ((Rect)->right) ? 0 : ((Rect)->right) - ((Rect)->left) + 1)
#define ConioLockConsole(ProcessData, Handle, Ptr) \
Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), CONIO_CONSOLE_MAGIC)
#define ConioLockConsole(ProcessData, Handle, Ptr, Access) \
Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_CONSOLE_MAGIC)
#define ConioUnlockConsole(Console) \
Win32CsrUnlockObject((Object_t *) Console)
#define ConioLockScreenBuffer(ProcessData, Handle, Ptr) \
Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), CONIO_SCREEN_BUFFER_MAGIC)
#define ConioLockScreenBuffer(ProcessData, Handle, Ptr, Access) \
Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_SCREEN_BUFFER_MAGIC)
#define ConioUnlockScreenBuffer(Buff) \
Win32CsrUnlockObject((Object_t *) Buff)
#define ConioChangeIcon(Console, hWindowIcon) (Console)->Vtbl->ChangeIcon(Console, hWindowIcon)

View file

@ -24,12 +24,14 @@ NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle,
Object_t **Object,
DWORD Access,
long Type);
VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle,
Object_t **Object);
Object_t **Object,
DWORD Access);
NTSTATUS FASTCALL Win32CsrReleaseObjectByPointer(Object_t *Object);
NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Object);

View file

@ -397,6 +397,7 @@ CSR_API(CsrFreeConsole)
Console = ProcessData->Console;
ProcessData->Console = NULL;
RemoveEntryList(&ProcessData->ProcessEntry);
if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
{
ConioDeleteConsole((Object_t *) Console);
@ -578,7 +579,7 @@ CSR_API(CsrReadConsole)
Buffer = Request->Data.ReadConsoleRequest.Buffer;
UnicodeBuffer = (PWCHAR)Buffer;
Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
&Console);
&Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -889,7 +890,7 @@ CSR_API(CsrWriteConsole)
if (Buffer)
{
Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
Request->Status = ConioWriteConsole(Console, Buff, Buffer,
@ -1317,7 +1318,7 @@ CSR_API(CsrGetScreenBufferInfo)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -1360,7 +1361,7 @@ CSR_API(CsrSetCursor)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -1480,7 +1481,8 @@ CSR_API(CsrWriteConsoleOutputChar)
{
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
&Buff);
&Buff,
GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
X = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
@ -1546,7 +1548,7 @@ CSR_API(CsrFillOutputChar)
return Request->Status = Status;
}
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -1605,7 +1607,7 @@ CSR_API(CsrReadInputEvent)
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console);
Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -1702,7 +1704,8 @@ CSR_API(CsrWriteConsoleOutputAttrib)
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
&Buff);
&Buff,
GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -1766,7 +1769,7 @@ CSR_API(CsrFillOutputAttrib)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -1817,7 +1820,7 @@ CSR_API(CsrGetCursorInfo)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -1848,7 +1851,7 @@ CSR_API(CsrSetCursorInfo)
return Request->Status = Status;
}
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -1900,7 +1903,7 @@ CSR_API(CsrSetTextAttrib)
return Request->Status = Status;
}
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -1936,7 +1939,7 @@ CSR_API(CsrSetConsoleMode)
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = Win32CsrGetObject(ProcessData,
Request->Data.SetConsoleModeRequest.ConsoleHandle,
(Object_t **) &Console);
(Object_t **) &Console, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -1972,7 +1975,7 @@ CSR_API(CsrGetConsoleMode)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
(Object_t **) &Console);
(Object_t **) &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -2085,7 +2088,7 @@ CSR_API(CsrSetScreenBuffer)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -2234,7 +2237,8 @@ CSR_API(CsrWriteConsoleOutput)
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
&Buff);
&Buff,
GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -2321,7 +2325,8 @@ CSR_API(CsrFlushInputBuffer)
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockConsole(ProcessData,
Request->Data.FlushInputBufferRequest.ConsoleInput,
&Console);
&Console,
GENERIC_WRITE);
if(! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -2375,7 +2380,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -2478,7 +2483,7 @@ CSR_API(CsrReadConsoleOutputChar)
return Request->Status = Status;
}
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
@ -2548,7 +2553,7 @@ CSR_API(CsrReadConsoleOutputAttrib)
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -2609,7 +2614,7 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -2654,7 +2659,7 @@ CSR_API(CsrPeekConsoleInput)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
if(! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -2732,7 +2737,7 @@ CSR_API(CsrReadConsoleOutput)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -2821,7 +2826,7 @@ CSR_API(CsrWriteConsoleInput)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console);
Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
return Request->Status = Status;
@ -2915,7 +2920,8 @@ CSR_API(CsrHardwareStateProperty)
Status = ConioLockConsole(ProcessData,
Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
&Console);
&Console,
GENERIC_READ);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");

View file

@ -106,20 +106,22 @@ Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
NTSTATUS FASTCALL
Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle,
Object_t **Object)
Object_t **Object,
DWORD Access)
{
return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, 0);
return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access);
}
NTSTATUS FASTCALL
Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle,
Object_t **Object,
DWORD Access,
LONG Type)
{
NTSTATUS Status;
Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, 0);
Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access);
if (! NT_SUCCESS(Status))
{
return Status;