Bitdefender Hypervisor Memory Introspection
udlist.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "udlist.h"
6 #include "guests.h"
7 
24 
27 
28 
31  _In_ const QWORD Cr3,
32  _In_ const QWORD Rip,
33  _In_ const QWORD Thread,
34  _Out_ INFO_UD_PENDING **CurrentPendingUD
35  )
51 {
52  INFO_UD_PENDING *infoUD;
53 
54  if (0 == Cr3)
55  {
57  }
58 
59  if (0 == Rip)
60  {
62  }
63 
64  if (0 == Thread)
65  {
67  }
68 
69  if (NULL == CurrentPendingUD)
70  {
72  }
73 
74  infoUD = HpAllocWithTag(sizeof(*infoUD), IC_TAG_UDCX);
75  if (NULL == infoUD)
76  {
78  }
79 
80  infoUD->Cr3 = Cr3;
81  infoUD->Rip = Rip;
82  infoUD->Thread = Thread;
83 
84  // Add the entry to the list of pending UDs
85  InsertTailList(&gListPendingUD, &infoUD->Link);
86 
87  // After #UD is injected (IntHandleEventInjection), we will remove the entry from the list and for that,
88  // we need to keep this info
89  *CurrentPendingUD = infoUD;
90 
91  return INT_STATUS_SUCCESS;
92 }
93 
94 
95 void
97  _Inout_ INFO_UD_PENDING **InfoUD
98  )
106 {
107  if (NULL != InfoUD && NULL != *InfoUD)
108  {
109  RemoveEntryList(&(*InfoUD)->Link);
111  }
112 }
113 
114 
115 void
117  _In_ const QWORD Cr3
118  )
126 {
127  list_for_each(gListPendingUD, INFO_UD_PENDING, pInfoUD)
128  {
129  if (Cr3 == pInfoUD->Cr3)
130  {
131  WARNING("[WARNING] There are still pending UDs in the list when process terminates (will remove them) "
132  "CR3: 0x%016llx RIP: 0x%016llx THREAD: 0x%016llx\n",
133  pInfoUD->Cr3, pInfoUD->Rip, pInfoUD->Thread);
134 
135  for (DWORD index = 0; index < gGuest.CpuCount; index++)
136  {
137  if (pInfoUD == gGuest.VcpuArray[index].CurrentUD)
138  {
139  gGuest.VcpuArray[index].CurrentUD = NULL;
140  }
141  }
142 
143  IntUDRemoveEntry(&pInfoUD);
144  }
145  }
146 }
147 
148 
151  _In_ const QWORD Cr3,
152  _In_ const QWORD Rip,
153  _In_ const QWORD Thread
154  )
164 {
165  list_for_each(gListPendingUD, INFO_UD_PENDING, pInfoUD)
166  {
167  if (Cr3 == pInfoUD->Cr3 && Rip == pInfoUD->Rip && Thread == pInfoUD->Thread)
168  {
169  TRACE("[INFO] Already an UD pending for CR3: 0x%016llx RIP: 0x%016llx THREAD: 0x%016llx\n",
170  pInfoUD->Cr3, pInfoUD->Rip, pInfoUD->Thread);
171 
172  return pInfoUD;
173  }
174  }
175 
176  return NULL;
177 }
#define _Out_
Definition: intro_sal.h:22
INTSTATUS IntUDAddToPendingList(const QWORD Cr3, const QWORD Rip, const QWORD Thread, INFO_UD_PENDING **CurrentPendingUD)
Add a new UD to the list of pending injections.
Definition: udlist.c:30
#define _In_
Definition: intro_sal.h:21
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
void IntUDRemoveEntry(INFO_UD_PENDING **InfoUD)
Remove a pending UD entry.
Definition: udlist.c:96
QWORD Cr3
Target virtual address space.
Definition: udlist.h:17
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
int INTSTATUS
The status data type.
Definition: introstatus.h:24
PVCPU_STATE VcpuArray
Array of the VCPUs assigned to this guest. The index in this array matches the VCPU number...
Definition: guests.h:372
QWORD Thread
Software thread ID.
Definition: udlist.h:19
#define _Inout_
Definition: intro_sal.h:20
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
Definition: introlists.h:87
unsigned long long QWORD
Definition: intro_types.h:53
#define INT_STATUS_INVALID_PARAMETER_4
Definition: introstatus.h:71
#define TRACE(fmt,...)
Definition: glue.h:58
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
INFO_UD_PENDING * CurrentUD
The currently pending #UD injection on this CPU.
Definition: guests.h:123
LIST_HEAD gListPendingUD
The list of pending UD injections. Once a UD gets injected, its entry will be removed from this list...
Definition: udlist.c:26
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
Definition: introlists.h:135
LIST_ENTRY Link
List entry element.
Definition: udlist.h:16
#define WARNING(fmt,...)
Definition: glue.h:60
void IntUDRemoveAllEntriesForCr3(const QWORD Cr3)
Remove all pending UD entries for a given virtual address space.
Definition: udlist.c:116
DWORD CpuCount
The number of logical CPUs.
Definition: guests.h:279
uint32_t DWORD
Definition: intro_types.h:49
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
INFO_UD_PENDING * IntUDGetEntry(const QWORD Cr3, const QWORD Rip, const QWORD Thread)
Get a UD entry for the provided Cr3, Rip and Thread ID.
Definition: udlist.c:150
#define LIST_HEAD_INIT(Name)
Definition: introlists.h:39
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
#define IC_TAG_UDCX
UD pending context.
Definition: memtags.h:85
#define list_for_each(_head, _struct_type, _var)
Definition: introlists.h:41
#define INT_STATUS_INVALID_PARAMETER_2
Definition: introstatus.h:65
QWORD Rip
The Rip.
Definition: udlist.h:18
#define INT_STATUS_INSUFFICIENT_RESOURCES
Definition: introstatus.h:281
#define INT_STATUS_INVALID_PARAMETER_3
Definition: introstatus.h:68