mirror of
https://github.com/reactos/reactos.git
synced 2025-06-30 21:01:21 +00:00
NtAdjustPrivilegesToken: Probe and capture parameters before use.
See issue #5497 for more details. svn path=/trunk/; revision=48707
This commit is contained in:
parent
3995cce1ba
commit
b9159984e7
1 changed files with 101 additions and 31 deletions
|
@ -1953,11 +1953,13 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
|
OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
|
||||||
OUT PULONG ReturnLength OPTIONAL)
|
OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
// PLUID_AND_ATTRIBUTES Privileges;
|
PLUID_AND_ATTRIBUTES CapturedPrivileges = NULL;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
ULONG CapturedCount = 0;
|
||||||
|
ULONG CapturedLength = 0;
|
||||||
|
ULONG NewStateSize = 0;
|
||||||
ULONG PrivilegeCount;
|
ULONG PrivilegeCount;
|
||||||
PTOKEN Token;
|
PTOKEN Token;
|
||||||
// ULONG Length;
|
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG j;
|
ULONG j;
|
||||||
ULONG k;
|
ULONG k;
|
||||||
|
@ -1973,30 +1975,95 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
|
|
||||||
DPRINT ("NtAdjustPrivilegesToken() called\n");
|
DPRINT ("NtAdjustPrivilegesToken() called\n");
|
||||||
|
|
||||||
// PrivilegeCount = NewState->PrivilegeCount;
|
|
||||||
PreviousMode = KeGetPreviousMode ();
|
PreviousMode = KeGetPreviousMode ();
|
||||||
// SeCaptureLuidAndAttributesArray(NewState->Privileges,
|
if (PreviousMode != KernelMode)
|
||||||
// PrivilegeCount,
|
{
|
||||||
// PreviousMode,
|
_SEH2_TRY
|
||||||
// NULL,
|
{
|
||||||
// 0,
|
/* Probe NewState */
|
||||||
// NonPagedPool,
|
if (DisableAllPrivileges == FALSE)
|
||||||
// 1,
|
{
|
||||||
// &Privileges,
|
ProbeForRead(NewState,
|
||||||
// &Length);
|
sizeof(TOKEN_PRIVILEGES),
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (TokenHandle,
|
CapturedCount = NewState->PrivilegeCount;
|
||||||
TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
|
NewStateSize = (ULONG)sizeof(TOKEN_PRIVILEGES) +
|
||||||
SepTokenObjectType,
|
((CapturedCount - ANYSIZE_ARRAY) * (ULONG)sizeof(LUID_AND_ATTRIBUTES));
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Token,
|
ProbeForRead(NewState,
|
||||||
NULL);
|
NewStateSize,
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Probe PreviousState and ReturnLength */
|
||||||
|
if (PreviousState != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWrite(PreviousState,
|
||||||
|
BufferLength,
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
ProbeForWrite(ReturnLength,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Return the exception code */
|
||||||
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DisableAllPrivileges == FALSE)
|
||||||
|
CapturedCount = NewState->PrivilegeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DisableAllPrivileges == FALSE)
|
||||||
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
/* Capture the new state array of privileges */
|
||||||
|
Status = SeCaptureLuidAndAttributesArray(NewState->Privileges,
|
||||||
|
CapturedCount,
|
||||||
|
PreviousMode,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
PagedPool,
|
||||||
|
TRUE,
|
||||||
|
&CapturedPrivileges,
|
||||||
|
&CapturedLength);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Return the exception code */
|
||||||
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference the token */
|
||||||
|
Status = ObReferenceObjectByHandle(TokenHandle,
|
||||||
|
TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
|
||||||
|
SepTokenObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Token,
|
||||||
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
|
DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
|
||||||
// SeReleaseLuidAndAttributesArray(Privileges,
|
|
||||||
// PreviousMode,
|
/* Release the captured privileges */
|
||||||
// 0);
|
if (CapturedPrivileges != NULL)
|
||||||
|
SeReleaseLuidAndAttributesArray(CapturedPrivileges,
|
||||||
|
PreviousMode,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2061,20 +2128,20 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
Count = 0;
|
Count = 0;
|
||||||
for (i = 0; i < Token->PrivilegeCount; i++)
|
for (i = 0; i < Token->PrivilegeCount; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < NewState->PrivilegeCount; j++)
|
for (j = 0; j < CapturedCount; j++)
|
||||||
{
|
{
|
||||||
if (Token->Privileges[i].Luid.LowPart == NewState->Privileges[j].Luid.LowPart &&
|
if (Token->Privileges[i].Luid.LowPart == CapturedPrivileges[j].Luid.LowPart &&
|
||||||
Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart)
|
Token->Privileges[i].Luid.HighPart == CapturedPrivileges[j].Luid.HighPart)
|
||||||
{
|
{
|
||||||
DPRINT ("Found privilege\n");
|
DPRINT ("Found privilege\n");
|
||||||
|
|
||||||
if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
|
if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
|
||||||
(NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED))
|
(CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED))
|
||||||
{
|
{
|
||||||
DPRINT ("Attributes differ\n");
|
DPRINT ("Attributes differ\n");
|
||||||
DPRINT ("Current attributes %lx desired attributes %lx\n",
|
DPRINT ("Current attributes %lx desired attributes %lx\n",
|
||||||
Token->Privileges[i].Attributes,
|
Token->Privileges[i].Attributes,
|
||||||
NewState->Privileges[j].Attributes);
|
CapturedPrivileges[j].Attributes);
|
||||||
|
|
||||||
/* Save current privilege */
|
/* Save current privilege */
|
||||||
if (PreviousState != NULL)
|
if (PreviousState != NULL)
|
||||||
|
@ -2100,7 +2167,7 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
/* Update current privlege */
|
/* Update current privlege */
|
||||||
Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
|
Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
|
||||||
Token->Privileges[i].Attributes |=
|
Token->Privileges[i].Attributes |=
|
||||||
(NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED);
|
(CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED);
|
||||||
DPRINT ("New attributes %lx\n",
|
DPRINT ("New attributes %lx\n",
|
||||||
Token->Privileges[i].Attributes);
|
Token->Privileges[i].Attributes);
|
||||||
}
|
}
|
||||||
|
@ -2110,7 +2177,7 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;
|
Status = Count < CapturedCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReturnLength != NULL)
|
if (ReturnLength != NULL)
|
||||||
|
@ -2119,11 +2186,14 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
(sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
|
(sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dereference the token */
|
||||||
ObDereferenceObject (Token);
|
ObDereferenceObject (Token);
|
||||||
|
|
||||||
// SeReleaseLuidAndAttributesArray(Privileges,
|
/* Release the captured privileges */
|
||||||
// PreviousMode,
|
if (CapturedPrivileges != NULL)
|
||||||
// 0);
|
SeReleaseLuidAndAttributesArray(CapturedPrivileges,
|
||||||
|
PreviousMode,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
DPRINT ("NtAdjustPrivilegesToken() done\n");
|
DPRINT ("NtAdjustPrivilegesToken() done\n");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue