https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a340ec17677fbad860a23…
commit a340ec17677fbad860a238f88a01f11a9130dd78
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Thu Mar 4 02:43:30 2021 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Mar 4 04:43:30 2021 +0300
[NTOS:PS] Guard the quota in a spin lock (#3419)
Prior to acquiring a quota from the process and do whatever it's needed to do (charge it or return it back), we must guard ourselves with a spinlock so that we may not get into potential race conditions. In Windows Server 2003, PspGivebackQuota and PspExpandQuota do the same thing and they're the equivalent to PspReturnProcessQuotaSpecifiedPool and PspChargeProcessQuotaSpecifiedPool in our codebase.
---
ntoskrnl/ps/quota.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/ntoskrnl/ps/quota.c b/ntoskrnl/ps/quota.c
index 0645654a320..947f78a658e 100644
--- a/ntoskrnl/ps/quota.c
+++ b/ntoskrnl/ps/quota.c
@@ -38,28 +38,32 @@ PspChargeProcessQuotaSpecifiedPool(IN PEPROCESS Process,
IN PS_QUOTA_TYPE QuotaType,
IN SIZE_T Amount)
{
+ KIRQL OldIrql;
ASSERT(Process);
ASSERT(Process != PsInitialSystemProcess);
ASSERT(QuotaType < PsQuotaTypes);
ASSERT(Process->QuotaBlock);
- /* Note: Race warning. TODO: Needs to add/use lock for this */
+ /* Guard our quota in a spin lock */
+ KeAcquireSpinLock(&PspQuotaLock, &OldIrql);
+
if (Process->QuotaUsage[QuotaType] + Amount >
Process->QuotaBlock->QuotaEntry[QuotaType].Limit)
{
DPRINT1("Quota exceeded, but ROS will let it slide...\n");
+ KeReleaseSpinLock(&PspQuotaLock, OldIrql);
return STATUS_SUCCESS;
//return STATUS_QUOTA_EXCEEDED; /* caller raises the exception */
}
InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[QuotaType], Amount);
- /* Note: Race warning. TODO: Needs to add/use lock for this */
if (Process->QuotaPeak[QuotaType] < Process->QuotaUsage[QuotaType])
{
Process->QuotaPeak[QuotaType] = Process->QuotaUsage[QuotaType];
}
+ KeReleaseSpinLock(&PspQuotaLock, OldIrql);
return STATUS_SUCCESS;
}
@@ -73,10 +77,15 @@ PspReturnProcessQuotaSpecifiedPool(IN PEPROCESS Process,
IN PS_QUOTA_TYPE QuotaType,
IN SIZE_T Amount)
{
+ KIRQL OldIrql;
ASSERT(Process);
ASSERT(Process != PsInitialSystemProcess);
ASSERT(QuotaType < PsQuotaTypes);
ASSERT(!(Amount & 0x80000000)); /* we need to be able to negate it */
+
+ /* Guard our quota in a spin lock */
+ KeAcquireSpinLock(&PspQuotaLock, &OldIrql);
+
if (Process->QuotaUsage[QuotaType] < Amount)
{
DPRINT1("WARNING: Process->QuotaUsage sanity check failed.\n");
@@ -86,6 +95,8 @@ PspReturnProcessQuotaSpecifiedPool(IN PEPROCESS Process,
InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[QuotaType],
-(LONG)Amount);
}
+
+ KeReleaseSpinLock(&PspQuotaLock, OldIrql);
}
/* FUNCTIONS ***************************************************************/