A watchdog timer is used to prevent the deprivileged mode running for too long,
aimed at handling a bug or attempted DoS. If the watchdog has occurred more than
once whilst we have been in the same deprivileged mode context, then we crash
the domain. This can be adjusted for longer running times in future.

Signed-off-by: Ben Catterall <ben.catter...@citrix.com>

Changed since v2:
 * Coding style: Added space after if
---
 xen/arch/x86/hvm/deprivileged.c |  4 ++++
 xen/arch/x86/nmi.c              | 17 +++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/xen/arch/x86/hvm/deprivileged.c b/xen/arch/x86/hvm/deprivileged.c
index 68c40ad..0b02065 100644
--- a/xen/arch/x86/hvm/deprivileged.c
+++ b/xen/arch/x86/hvm/deprivileged.c
@@ -8,6 +8,7 @@
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/sched.h>
+#include <xen/watchdog.h>
 #include <asm/paging.h>
 #include <xen/compiler.h>
 #include <asm/hap.h>
@@ -17,6 +18,7 @@
 #include <xen/domain_page.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <xen/hvm/deprivileged.h>
+#include <xen/hvm/deprivileged_syscall.h>
 
 void hvm_deprivileged_init(struct domain *d, l4_pgentry_t *l4t_base)
 {
@@ -577,6 +579,8 @@ int hvm_deprivileged_user_mode(void)
     vcpu->arch.hvm_vcpu.depriv_user_mode = 0;
     vcpu->arch.hvm_vcpu.depriv_rsp = 0;
 
+    vcpu->arch.hvm_vcpu.depriv_watchdog_count = 0;
+
     /*
      * If we need to crash the domain at this point. We will return up the call
      * stack, undoing any allocations and then the event testers in the exit
diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c
index 2ab97a0..e5598a2 100644
--- a/xen/arch/x86/nmi.c
+++ b/xen/arch/x86/nmi.c
@@ -26,6 +26,7 @@
 #include <xen/smp.h>
 #include <xen/keyhandler.h>
 #include <xen/cpu.h>
+#include <xen/hvm/deprivileged.h>
 #include <asm/current.h>
 #include <asm/mc146818rtc.h>
 #include <asm/msr.h>
@@ -463,9 +464,25 @@ int __init watchdog_setup(void)
 /* Returns false if this was not a watchdog NMI, true otherwise */
 bool_t nmi_watchdog_tick(const struct cpu_user_regs *regs)
 {
+    struct vcpu *vcpu = current;
     bool_t watchdog_tick = 1;
     unsigned int sum = this_cpu(nmi_timer_ticks);
 
+    /*
+     * If the domain has been running in deprivileged mode for two watchdog
+     * ticks, then we kill it to prevent a DoS. We use two ticks as a coarse
+     * measure as this ensures that at least a full watchdog tick duration has
+     * occurred. This means that we do not need to track entry time and do
+     * time calculations.
+     */
+    if ( is_hvm_deprivileged_vcpu() )
+    {
+        if ( vcpu->arch.hvm_vcpu.depriv_watchdog_count )
+            hvm_deprivileged_crash_domain("HVM Deprivileged domain: Domain 
exceeded running time.");
+        else
+            vcpu->arch.hvm_vcpu.depriv_watchdog_count = 1;
+    }
+
     if ( (this_cpu(last_irq_sums) == sum) && watchdog_enabled() )
     {
         /*
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

Reply via email to