1. fixed prototypes of NtSetSystemTime and NtQuerySystemTime and made them handle passed buffers securely

2. check for the SeSystemtimePrivilege privilege in NtSetSystemTime()
3. write debug messages when privileges are missing

svn path=/trunk/; revision=13235
This commit is contained in:
Thomas Bluemel 2005-01-23 23:02:19 +00:00
parent 4301549d0d
commit 7c02041548
6 changed files with 87 additions and 32 deletions

View file

@ -1638,7 +1638,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
KeyCell->Flags |= REG_KEY_LINK_CELL; KeyCell->Flags |= REG_KEY_LINK_CELL;
} }
NtQuerySystemTime (&KeyCell->LastWriteTime); ZwQuerySystemTime (&KeyCell->LastWriteTime);
CmiMarkBlockDirty (RegistryHive, KeyObject->KeyCellOffset); CmiMarkBlockDirty (RegistryHive, KeyObject->KeyCellOffset);
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
@ -1683,7 +1683,7 @@ NtDeleteValueKey (IN HANDLE KeyHandle,
KeyObject->KeyCellOffset, KeyObject->KeyCellOffset,
ValueName); ValueName);
NtQuerySystemTime (&KeyObject->KeyCell->LastWriteTime); ZwQuerySystemTime (&KeyObject->KeyCell->LastWriteTime);
CmiMarkBlockDirty (KeyObject->RegistryHive, KeyObject->KeyCellOffset); CmiMarkBlockDirty (KeyObject->RegistryHive, KeyObject->KeyCellOffset);
/* Release hive lock */ /* Release hive lock */

View file

@ -178,6 +178,7 @@ NtCreateProfile(OUT PHANDLE ProfileHandle,
if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege, if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege,
PreviousMode)) PreviousMode))
{ {
DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n");
return STATUS_PRIVILEGE_NOT_HELD; return STATUS_PRIVILEGE_NOT_HELD;
} }
} }

View file

@ -154,6 +154,7 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
RtlReleaseCapturedUnicodeString(&WName, RtlReleaseCapturedUnicodeString(&WName,
PreviousMode, PreviousMode,
FALSE); FALSE);
DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
return STATUS_PRIVILEGE_NOT_HELD; return STATUS_PRIVILEGE_NOT_HELD;
} }
@ -295,6 +296,7 @@ NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName,
} }
else else
{ {
DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
Status = STATUS_PRIVILEGE_NOT_HELD; Status = STATUS_PRIVILEGE_NOT_HELD;
} }

View file

@ -142,28 +142,57 @@ ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
* RETURNS: Status * RETURNS: Status
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
NtSetSystemTime(IN PLARGE_INTEGER UnsafeNewSystemTime, NtSetSystemTime(IN PLARGE_INTEGER SystemTime,
OUT PLARGE_INTEGER UnsafeOldSystemTime OPTIONAL) OUT PLARGE_INTEGER PreviousTime OPTIONAL)
{ {
LARGE_INTEGER OldSystemTime; LARGE_INTEGER OldSystemTime;
LARGE_INTEGER NewSystemTime; LARGE_INTEGER NewSystemTime;
LARGE_INTEGER LocalTime; LARGE_INTEGER LocalTime;
TIME_FIELDS TimeFields; TIME_FIELDS TimeFields;
NTSTATUS Status; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
/* FIXME: Check for SeSystemTimePrivilege */ PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(SystemTime,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
NewSystemTime = *SystemTime;
if(PreviousTime != NULL)
{
ProbeForWrite(PreviousTime,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
Status = MmCopyFromCaller(&NewSystemTime, UnsafeNewSystemTime,
sizeof(NewSystemTime));
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
return Status; return Status;
} }
}
if (UnsafeOldSystemTime != NULL) if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege,
PreviousMode))
{
DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
return STATUS_PRIVILEGE_NOT_HELD;
}
if(PreviousTime != NULL)
{ {
KeQuerySystemTime(&OldSystemTime); KeQuerySystemTime(&OldSystemTime);
} }
ExSystemTimeToLocalTime(&NewSystemTime, ExSystemTimeToLocalTime(&NewSystemTime,
&LocalTime); &LocalTime);
RtlTimeToTimeFields(&LocalTime, RtlTimeToTimeFields(&LocalTime,
@ -173,14 +202,17 @@ NtSetSystemTime(IN PLARGE_INTEGER UnsafeNewSystemTime,
/* Set system time */ /* Set system time */
KiSetSystemTime(&NewSystemTime); KiSetSystemTime(&NewSystemTime);
if (UnsafeOldSystemTime != NULL) if(PreviousTime != NULL)
{ {
Status = MmCopyToCaller(UnsafeOldSystemTime, &OldSystemTime, _SEH_TRY
sizeof(OldSystemTime));
if (!NT_SUCCESS(Status))
{ {
return Status; *PreviousTime = OldSystemTime;
} }
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -194,19 +226,38 @@ NtSetSystemTime(IN PLARGE_INTEGER UnsafeNewSystemTime,
* time of day in the standard time format. * time of day in the standard time format.
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
NtQuerySystemTime(OUT PLARGE_INTEGER UnsafeCurrentTime) NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
{ {
LARGE_INTEGER CurrentTime; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
KeQuerySystemTime(&CurrentTime); PreviousMode = ExGetPreviousMode();
Status = MmCopyToCaller(UnsafeCurrentTime, &CurrentTime,
sizeof(CurrentTime)); if(PreviousMode != KernelMode)
if (!NT_SUCCESS(Status))
{ {
return(Status); _SEH_TRY
{
ProbeForRead(SystemTime,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
/* it's safe to pass the pointer directly to KeQuerySystemTime as it's just
a basic copy to these pointer, if it raises an exception nothing dangerous
can happen! */
KeQuerySystemTime(SystemTime);
} }
return STATUS_SUCCESS; _SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
else
{
KeQuerySystemTime(SystemTime);
}
return Status;
} }

View file

@ -256,7 +256,7 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
NtQuerySystemTime (&SymbolicLink->CreateTime); ZwQuerySystemTime (&SymbolicLink->CreateTime);
DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__); DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
ObDereferenceObject(SymbolicLink); ObDereferenceObject(SymbolicLink);

View file

@ -1932,6 +1932,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
if(!SeSinglePrivilegeCheck(SeTcbPrivilege, if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
PreviousMode)) PreviousMode))
{ {
DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n");
/* can't set the session id, bail! */ /* can't set the session id, bail! */
Status = STATUS_PRIVILEGE_NOT_HELD; Status = STATUS_PRIVILEGE_NOT_HELD;
break; break;