diff --git a/ksm.c b/ksm.c
index d5f2ce7..0f746e2 100644
--- a/ksm.c
+++ b/ksm.c
@@ -142,6 +142,11 @@ int __ksm_init_cpu(struct ksm *k)
}
vcpu = ksm_cpu(k);
+ if (vcpu->subverted) {
+ VCPU_DEBUG_RAW("CPU already subverted\n");
+ return 0;
+ }
+
ret = vcpu_create(vcpu);
if (ret < 0) {
VCPU_DEBUG_RAW("failed to create vcpu, oom?\n");
diff --git a/ksm/ksm/ksm.vcxproj b/ksm/ksm/ksm.vcxproj
index 0076a33..13743c3 100644
--- a/ksm/ksm/ksm.vcxproj
+++ b/ksm/ksm/ksm.vcxproj
@@ -21,8 +21,7 @@
-
-
+ Windows7
true
WindowsKernelModeDriver10.0
Driver
diff --git a/main_linux.c b/main_linux.c
index c878919..aefebb9 100644
--- a/main_linux.c
+++ b/main_linux.c
@@ -25,6 +25,9 @@
#include "um/um.h"
static struct mm_struct *mm = NULL;
+static int major_no = 0;
+static struct class *class;
+
static long ksm_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
{
int ret = -EINVAL;
@@ -103,8 +106,17 @@ static struct file_operations ksm_fops = {
.release = ksm_release,
.unlocked_ioctl = ksm_ioctl,
};
-static int major_no = 0;
-static struct class *class;
+
+static int ksm_reboot(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ kms_exit(ksm);
+ return 0;
+}
+
+static struct notifier_block reboot_notify = {
+ .notifier_call = ksm_reboot,
+};
static int __init ksm_start(void)
{
@@ -126,6 +138,7 @@ static int __init ksm_start(void)
dev = device_create(class, NULL, MKDEV(major_no, 0), NULL, UM_DEVICE_NAME);
if (dev) {
+ register_reboot_notifier(&reboot_notify);
VCPU_DEBUG_RAW("ready\n");
return ret;
}
@@ -150,6 +163,7 @@ static void __exit ksm_cleanup(void)
class_unregister(class);
class_destroy(class);
unregister_chrdev(major_no, UM_DEVICE_NAME);
+ unregister_reboot_notifier(&reboot_notify);
active = ksm->active_vcpus;
ret = ksm_free(ksm);
diff --git a/main_nt.c b/main_nt.c
index ac0d01d..2e6bc79 100644
--- a/main_nt.c
+++ b/main_nt.c
@@ -109,6 +109,7 @@ static void DriverUnload(PDRIVER_OBJECT driverObject)
print_exit();
#endif
IoDeleteSymbolicLink(&deviceLink);
+ IoUnregisterShutdownNotification(driverObject->DeviceObject);
IoDeleteDevice(driverObject->DeviceObject);
}
@@ -120,7 +121,8 @@ static NTSTATUS DriverDispatch(PDEVICE_OBJECT deviceObject, PIRP irp)
u32 inlen = stack->Parameters.DeviceIoControl.InputBufferLength;
u32 ioctl;
- if (stack->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
+ switch (stack->MajorFunction) {
+ case IRP_MJ_DEVICE_CONTROL:
ioctl = stack->Parameters.DeviceIoControl.IoControlCode;
VCPU_DEBUG("%s: IOCTL: 0x%08X\n", proc_name(), ioctl);
@@ -143,6 +145,11 @@ static NTSTATUS DriverDispatch(PDEVICE_OBJECT deviceObject, PIRP irp)
status = STATUS_NOT_SUPPORTED;
break;
}
+ break;
+ case IRP_MJ_SHUTDOWN:
+ /* Ignore return value */
+ ksm_free(ksm);
+ break;
}
irp->IoStatus.Status = status;
@@ -187,6 +194,9 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING registryPath)
if (!NT_SUCCESS(status))
goto exit;
+ if (!NT_SUCCESS(IoRegisterShutdownNotification(deviceObject)))
+ goto err2;
+
driverObject->DriverUnload = DriverUnload;
driverObject->MajorFunction[IRP_MJ_CREATE] =
driverObject->MajorFunction[IRP_MJ_CLOSE] =
@@ -198,6 +208,8 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING registryPath)
goto out;
}
+ IoUnregisterShutdownNotification(deviceObject);
+err2:
IoDeleteDevice(deviceObject);
exit:
ksm_free(ksm);
diff --git a/mm.h b/mm.h
index fb14b6d..9e3e012 100644
--- a/mm.h
+++ b/mm.h
@@ -245,6 +245,11 @@ static inline void __mm_free_pool(void *v)
kfree(v);
}
+static inline bool mm_is_kernel_addr(void *va)
+{
+ return va >= PAGE_OFFSET;
+}
+
extern void *mm_remap(u64 phys, size_t size);
extern void mm_unmap(void *addr, size_t size);
extern void *kmap_virt(void *addr, size_t len, pgprot_t prot);
@@ -377,6 +382,11 @@ static inline void __mm_free_pool(void *v)
{
ExFreePool(v);
}
+
+static inline bool mm_is_kernel_addr(void *va)
+{
+ return va >= MmSystemRangeStart;
+}
#endif
static inline void mm_free_pool(void *v, size_t size)
diff --git a/sandbox.c b/sandbox.c
index 74a4c5a..a256d04 100644
--- a/sandbox.c
+++ b/sandbox.c
@@ -284,8 +284,8 @@ bool ksm_sandbox_handle_ept(struct ept *ept, int dpl, u64 gpa,
pid = proc_id();
task = find_sa_task_pgd_pid(k, pid, cr3 & PAGE_PA_MASK);
if (!task) {
- dbgbreak();
- return false;
+ *eptp_switch = EPTP_DEFAULT;
+ return true;
}
eptp = task_eptp(task);
diff --git a/vcpu.c b/vcpu.c
index f2c72d3..9af4c13 100644
--- a/vcpu.c
+++ b/vcpu.c
@@ -151,9 +151,14 @@ static bool setup_pml4(struct ept *ept, int access, u16 eptp)
for (i = 0; i < ksm->range_count; ++i) {
range = &ksm->ranges[i];
- for (addr = range->start; addr < range->end; addr += PAGE_SIZE)
- if (!ept_alloc_page(EPT4(ept, eptp), access, addr, addr))
+ for (addr = range->start; addr < range->end; addr += PAGE_SIZE) {
+ int r = access;
+ if (mm_is_kernel_addr(__va(addr)))
+ r = EPT_ACCESS_ALL;
+
+ if (!ept_alloc_page(EPT4(ept, eptp), r, addr, addr))
return false;
+ }
}
/* Allocate APIC page */