summaryrefslogtreecommitdiff
path: root/sysutils/xenkernel41/patches/patch-CVE-2012-3498
blob: 66f1622a53c5714595c9aca69d552961cc4ba3a6 (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
$NetBSD: patch-CVE-2012-3498,v 1.1 2012/09/12 11:04:18 drochner Exp $

contains patch for CVE-2012-3495
see http://lists.xen.org/archives/html/xen-devel/2012-09/msg00187.html
and http://lists.xen.org/archives/html/xen-devel/2012-09/msg00197.html

--- xen/arch/x86/physdev.c.orig	2012-09-12 09:41:55.000000000 +0000
+++ xen/arch/x86/physdev.c
@@ -40,11 +40,18 @@ static int physdev_hvm_map_pirq(
         struct hvm_girq_dpci_mapping *girq;
         uint32_t machine_gsi = 0;
 
+        if ( map->index < 0 || map->index >= NR_HVM_IRQS )
+        {
+            ret = -EINVAL;
+            break;
+        }
+
         /* find the machine gsi corresponding to the
          * emulated gsi */
         hvm_irq_dpci = domain_get_irq_dpci(d);
         if ( hvm_irq_dpci )
         {
+            BUILD_BUG_ON(ARRAY_SIZE(hvm_irq_dpci->girq) < NR_HVM_IRQS);
             list_for_each_entry ( girq,
                                   &hvm_irq_dpci->girq[map->index],
                                   list )
@@ -587,11 +594,16 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
             break;
 
         spin_lock(&d->event_lock);
-        out.pirq = get_free_pirq(d, out.type, 0);
-        d->arch.pirq_irq[out.pirq] = PIRQ_ALLOCATED;
+        ret = get_free_pirq(d, out.type, 0);
+        if ( ret >= 0 )
+            d->arch.pirq_irq[ret] = PIRQ_ALLOCATED;
         spin_unlock(&d->event_lock);
 
-        ret = copy_to_guest(arg, &out, 1) ? -EFAULT : 0;
+        if ( ret >= 0 )
+        {
+            out.pirq = ret;
+            ret = copy_to_guest(arg, &out, 1) ? -EFAULT : 0;
+        }
 
         rcu_unlock_domain(d);
         break;