|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] All items in SYSTEM_PROCESSOR array may not be initialized
The SYSTEM_PROCESSOR array is allocated to fit the maximum number of supported
CPUs, but elements are only initialized when the SystemProcessorChangeCallback
callback is called with KeProcessorAddCompleteNotify.
Check if the SYSTEM_PROCESSOR structure is initialized before accessing any
other members, and fail SystemProcessorVcpuId with STATUS_NOT_SUPPORTED for any
uninitialized CPUs
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
src/xen/system.c | 21 ++++++++++++++++++++-
src/xenbus/evtchn.c | 22 ++++++++++++++++------
src/xenbus/evtchn_fifo.c | 8 ++++++--
src/xenbus/shared_info.c | 2 ++
4 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/src/xen/system.c b/src/xen/system.c
index f85efc4..7220faa 100644
--- a/src/xen/system.c
+++ b/src/xen/system.c
@@ -54,6 +54,7 @@ typedef struct _SYSTEM_PROCESSOR {
CHAR Manufacturer[13];
UCHAR ApicID;
UCHAR ProcessorID;
+ BOOLEAN Initialized;
NTSTATUS Status;
KEVENT Event;
vcpu_info_t *Vcpu;
@@ -643,9 +644,14 @@ SystemProcessorVcpuId(
if (Cpu >= Context->ProcessorCount)
goto fail1;
+ status = STATUS_NOT_SUPPORTED;
+ if (!Processor->Initialized)
+ goto fail2;
+
*vcpu_id = Processor->ProcessorID;
return STATUS_SUCCESS;
+fail2:
fail1:
return status;
}
@@ -666,14 +672,18 @@ SystemProcessorVcpuInfo(
goto fail1;
status = STATUS_NOT_SUPPORTED;
- if (Processor->Registered == NULL)
+ if (!Processor->Initialized)
goto fail2;
+ if (Processor->Registered == NULL)
+ goto fail3;
+
ASSERT(*Processor->Registered);
*Vcpu = Processor->Vcpu;
return STATUS_SUCCESS;
+fail3:
fail2:
fail1:
return status;
@@ -702,6 +712,8 @@ SystemProcessorRegisterVcpuInfo(
if (Cpu >= Context->ProcessorCount)
goto fail1;
+ ASSERT(Processor->Initialized);
+
ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
MdlMappedSystemVa = Mdl->MappedSystemVa;
@@ -864,6 +876,7 @@ SystemProcessorChangeCallback(
Processor = &Context->Processor[Cpu];
KeInitializeEvent(&Processor->Event, NotificationEvent, FALSE);
+ Processor->Initialized = TRUE;
KeInitializeDpc(&Processor->Dpc, SystemProcessorDpc, NULL);
KeSetImportanceDpc(&Processor->Dpc, HighImportance);
@@ -991,9 +1004,12 @@ SystemDeregisterProcessorChangeCallback(
for (Cpu = 0; Cpu < Context->ProcessorCount; Cpu++) {
PSYSTEM_PROCESSOR Processor = &Context->Processor[Cpu];
+ // Should check Processor->Initialized, but these operations are
harmless to
+ // uninitialized SYSTEM_PROCESSOR structures.
SystemProcessorDeregisterVcpuInfo(Cpu);
SystemProcessorTeardown(Cpu);
+ Processor->Initialized = FALSE;
RtlZeroMemory(&Processor->Dpc, sizeof (KDPC));
RtlZeroMemory(&Processor->Event, sizeof (KEVENT));
Processor->Status = 0;
@@ -1215,6 +1231,9 @@ SystemCheckProcessors(
{
PSYSTEM_PROCESSOR Processor = &Context->Processor[Cpu];
+ if (!Processor->Initialized)
+ continue;
+
(VOID) KeWaitForSingleObject(&Processor->Event,
Executive,
KernelMode,
diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c
index 8942cdf..ccc8f2e 100644
--- a/src/xenbus/evtchn.c
+++ b/src/xenbus/evtchn.c
@@ -284,11 +284,12 @@ EvtchnOpenVirq(
goto fail1;
status = SystemProcessorVcpuId(Cpu, &vcpu_id);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ goto fail2;
status = EventChannelBindVirq(Index, vcpu_id, &LocalPort);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail3;
Channel->Parameters.Virq.Index = Index;
@@ -296,6 +297,9 @@ EvtchnOpenVirq(
return STATUS_SUCCESS;
+fail3:
+ Error("fail3\n");
+
fail2:
Error("fail2\n");
@@ -769,11 +773,12 @@ EvtchnBind(
LocalPort = Channel->LocalPort;
status = SystemProcessorVcpuId(Cpu, &vcpu_id);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ goto fail2;
status = EventChannelBindVirtualCpu(LocalPort, vcpu_id);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail3;
Channel->Cpu = Cpu;
@@ -784,6 +789,9 @@ done:
return STATUS_SUCCESS;
+fail3:
+ Error("fail3\n");
+
fail2:
Error("fail2\n");
@@ -1292,7 +1300,8 @@ EvtchnInterruptEnable(
continue;
status = SystemProcessorVcpuId(Cpu, &vcpu_id);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ continue;
Vector = FdoGetInterruptVector(Context->Fdo, Processor->Interrupt);
@@ -1359,7 +1368,8 @@ EvtchnInterruptDisable(
continue;
status = SystemProcessorVcpuId(Cpu, &vcpu_id);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ continue;
(VOID) HvmSetEvtchnUpcallVector(vcpu_id, 0);
Processor->UpcallEnabled = FALSE;
diff --git a/src/xenbus/evtchn_fifo.c b/src/xenbus/evtchn_fifo.c
index 3b3f493..a8dab8c 100644
--- a/src/xenbus/evtchn_fifo.c
+++ b/src/xenbus/evtchn_fifo.c
@@ -514,13 +514,14 @@ EvtchnFifoAcquire(
goto fail1;
status = SystemProcessorVcpuId(Index, &vcpu_id);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ goto fail2;
Pfn = MmGetMdlPfnArray(Mdl)[0];
status = EventChannelInitControl(Pfn, vcpu_id);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail3;
Address.QuadPart = (ULONGLONG)Pfn << PAGE_SHIFT;
@@ -542,6 +543,9 @@ done:
return STATUS_SUCCESS;
+fail3:
+ Error("fail3\n");
+
fail2:
Error("fail2\n");
diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c
index 9f11979..786ffcf 100644
--- a/src/xenbus/shared_info.c
+++ b/src/xenbus/shared_info.c
@@ -639,6 +639,8 @@ SharedInfoAcquire(
Processor = &Context->Processor[Index];
status = SystemProcessorVcpuId(Index, &Processor->vcpu_id);
+ if (status == STATUS_NOT_SUPPORTED)
+ continue;
if (!NT_SUCCESS(status))
goto fail7;
--
2.33.0.windows.2
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |