]> git.pld-linux.org Git - packages/xen.git/blob - CVE-2014-2599.patch
Fix CVE-2014-2599
[packages/xen.git] / CVE-2014-2599.patch
1 commit babcef372ae2ca9c4f4212398803015eb250f764
2 Author: Jan Beulich <jbeulich@suse.com>
3 Date:   Tue Mar 25 17:20:47 2014 +0100
4
5     x86: enforce preemption in HVM_set_mem_access / p2m_set_mem_access()
6     
7     Processing up to 4G PFNs may take almost arbitrarily long, so
8     preemption is needed here.
9     
10     This is CVE-2014-2599 / XSA-89.
11     
12     Signed-off-by: Jan Beulich <jbeulich@suse.com>
13     Reviewed-by: Tim Deegan <tim@xen.org>
14     master commit: 0fe53c4f279e1a8ef913e71ed000236d21ce96de
15     master date: 2014-03-25 15:23:57 +0100
16
17 diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
18 index 69f7e74..6150899 100644
19 --- a/xen/arch/x86/hvm/hvm.c
20 +++ b/xen/arch/x86/hvm/hvm.c
21 @@ -4465,6 +4465,15 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
22              goto param_fail5;
23              
24          rc = p2m_set_mem_access(d, a.first_pfn, a.nr, a.hvmmem_access);
25 +        if ( rc > 0 )
26 +        {
27 +            a.first_pfn += a.nr - rc;
28 +            a.nr = rc;
29 +            if ( __copy_to_guest(arg, &a, 1) )
30 +                rc = -EFAULT;
31 +            else
32 +                rc = -EAGAIN;
33 +        }
34  
35      param_fail5:
36          rcu_unlock_domain(d);
37 diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
38 index 8f380ed..e0e5840 100644
39 --- a/xen/arch/x86/mm/p2m.c
40 +++ b/xen/arch/x86/mm/p2m.c
41 @@ -1366,15 +1366,14 @@ void p2m_mem_access_resume(struct domain *d)
42  
43  /* Set access type for a region of pfns.
44   * If start_pfn == -1ul, sets the default access type */
45 -int p2m_set_mem_access(struct domain *d, unsigned long start_pfn, 
46 -                       uint32_t nr, hvmmem_access_t access) 
47 +long p2m_set_mem_access(struct domain *d, unsigned long pfn, uint32_t nr,
48 +                        hvmmem_access_t access)
49  {
50      struct p2m_domain *p2m = p2m_get_hostp2m(d);
51 -    unsigned long pfn;
52      p2m_access_t a, _a;
53      p2m_type_t t;
54      mfn_t mfn;
55 -    int rc = 0;
56 +    long rc;
57  
58      /* N.B. _not_ static: initializer depends on p2m->default_access */
59      p2m_access_t memaccess[] = {
60 @@ -1397,14 +1396,17 @@ int p2m_set_mem_access(struct domain *d, unsigned long start_pfn,
61      a = memaccess[access];
62  
63      /* If request to set default access */
64 -    if ( start_pfn == ~0ull ) 
65 +    if ( pfn == ~0ul )
66      {
67          p2m->default_access = a;
68          return 0;
69      }
70  
71 +    if ( !nr )
72 +        return 0;
73 +
74      p2m_lock(p2m);
75 -    for ( pfn = start_pfn; pfn < start_pfn + nr; pfn++ )
76 +    for ( ; ; ++pfn )
77      {
78          mfn = p2m->get_entry(p2m, pfn, &t, &_a, 0, NULL);
79          if ( p2m->set_entry(p2m, pfn, mfn, PAGE_ORDER_4K, t, a) == 0 )
80 @@ -1412,6 +1414,13 @@ int p2m_set_mem_access(struct domain *d, unsigned long start_pfn,
81              rc = -ENOMEM;
82              break;
83          }
84 +
85 +        /* Check for continuation if it's not the last interation. */
86 +        if ( !--nr || hypercall_preempt_check() )
87 +        {
88 +            rc = nr;
89 +            break;
90 +        }
91      }
92      p2m_unlock(p2m);
93      return rc;
94 diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
95 index f4e7253..a2cb1b7 100644
96 --- a/xen/include/asm-x86/p2m.h
97 +++ b/xen/include/asm-x86/p2m.h
98 @@ -576,8 +576,8 @@ void p2m_mem_access_resume(struct domain *d);
99  
100  /* Set access type for a region of pfns.
101   * If start_pfn == -1ul, sets the default access type */
102 -int p2m_set_mem_access(struct domain *d, unsigned long start_pfn, 
103 -                       uint32_t nr, hvmmem_access_t access);
104 +long p2m_set_mem_access(struct domain *d, unsigned long start_pfn,
105 +                        uint32_t nr, hvmmem_access_t access);
106  
107  /* Get access type for a pfn
108   * If pfn == -1ul, gets the default access type */
This page took 0.072099 seconds and 4 git commands to generate.