summaryrefslogtreecommitdiff
path: root/sysutils/xenkernel41/patches/patch-CVE-2013-4355_1
blob: 42d622fed20d1d2d9c1eb80797c66725dc99e5ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
$NetBSD: patch-CVE-2013-4355_1,v 1.4 2014/05/05 13:39:10 drochner Exp $

http://lists.xenproject.org/archives/html/xen-devel/2013-09/msg03160.html
also fixes
http://lists.xenproject.org/archives/html/xen-devel/2013-11/msg03827.html
(CVE-2013-4554)
also fixes
http://lists.xenproject.org/archives/html/xen-devel/2014-03/msg03177.html
(CVE-2014-2599)
also fixes
http://lists.xenproject.org/archives/html/xen-devel/2014-04/msg03853.html
(CVE-2014-3124)

--- xen/arch/x86/hvm/hvm.c.orig	2013-09-10 06:42:18.000000000 +0000
+++ xen/arch/x86/hvm/hvm.c	2014-04-30 13:11:30.000000000 +0000
@@ -1961,11 +1961,7 @@ void hvm_task_switch(
 
     rc = hvm_copy_from_guest_virt(
         &tss, prev_tr.base, sizeof(tss), PFEC_page_present);
-    if ( rc == HVMCOPY_bad_gva_to_gfn )
-        goto out;
-    if ( rc == HVMCOPY_gfn_paged_out )
-        goto out;
-    if ( rc == HVMCOPY_gfn_shared )
+    if ( rc != HVMCOPY_okay )
         goto out;
 
     eflags = regs->eflags;
@@ -2010,13 +2006,11 @@ void hvm_task_switch(
 
     rc = hvm_copy_from_guest_virt(
         &tss, tr.base, sizeof(tss), PFEC_page_present);
-    if ( rc == HVMCOPY_bad_gva_to_gfn )
-        goto out;
-    if ( rc == HVMCOPY_gfn_paged_out )
-        goto out;
-    /* Note: this could be optimised, if the callee functions knew we want RO
-     * access */
-    if ( rc == HVMCOPY_gfn_shared )
+    /*
+     * Note: The HVMCOPY_gfn_shared case could be optimised, if the callee
+     * functions knew we want RO access.
+     */
+    if ( rc != HVMCOPY_okay )
         goto out;
 
 
@@ -2834,7 +2828,7 @@ int hvm_do_hypercall(struct cpu_user_reg
     case 4:
     case 2:
         hvm_get_segment_register(curr, x86_seg_ss, &sreg);
-        if ( unlikely(sreg.attr.fields.dpl == 3) )
+        if ( unlikely(sreg.attr.fields.dpl) )
         {
     default:
             regs->eax = -EPERM;
@@ -3657,13 +3651,9 @@ long do_hvm_op(unsigned long op, XEN_GUE
                 rc = -EINVAL;
                 goto param_fail4;
             } 
-            if ( p2m_is_grant(t) )
-            {
-                gdprintk(XENLOG_WARNING,
-                         "type for pfn 0x%lx changed to grant while "
-                         "we were working?\n", pfn);
+            if ( !p2m_is_ram(t) &&
+                 (!p2m_is_hole(t) || a.hvmmem_type != HVMMEM_mmio_dm) )
                 goto param_fail4;
-            }
             else
             {
                 nt = p2m_change_type(p2m, pfn, t, memtype[a.hvmmem_type]);
@@ -3746,7 +3736,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
              ((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) )
             goto param_fail5;
             
-        for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ )
+        for ( pfn = a.first_pfn; a.nr; ++pfn )
         {
             p2m_type_t t;
             mfn_t mfn;
@@ -3759,6 +3749,17 @@ long do_hvm_op(unsigned long op, XEN_GUE
             p2m_unlock(p2m);
             if ( !success )
                 goto param_fail5;
+
+            /* Check for continuation if it's not the last interation. */
+            if ( --a.nr && hypercall_preempt_check() )
+            {
+                a.first_pfn = pfn + 1;
+                if ( copy_to_guest(arg, &a, 1) )
+                    rc = -EFAULT;
+                else
+                    rc = -EAGAIN;
+                goto param_fail5;
+            }
         }
 
         rc = 0;