x86/mm: Prevent leaking domain mappings in paging_log_dirty_op()
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 17 Dec 2013 15:38:07 +0000 (16:38 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 17 Dec 2013 15:38:07 +0000 (16:38 +0100)
Coverity ID: 1135374 1135375 1135376 1135377

If {copy_to,clear}_guest_offset() fails, we would leak the domain mappings for
l4 thru l1.

Fixing this requires having conditional unmaps on the faulting path, which in
turn requires explicitly initialising the pointers to NULL because of the
early ENOMEM exit.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <JBeulich@suse.com>
Acked-by: Tim Deegan <tim@xen.org>
xen/arch/x86/mm/paging.c

index 4ba7669a340c2e91fa177c4abc3752bad8f0a31b..21344e50ff4d510844fb1571f14a904d73cca6e7 100644 (file)
@@ -330,8 +330,8 @@ int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc)
 {
     int rv = 0, clean = 0, peek = 1;
     unsigned long pages = 0;
-    mfn_t *l4, *l3, *l2;
-    unsigned long *l1;
+    mfn_t *l4 = NULL, *l3 = NULL, *l2 = NULL;
+    unsigned long *l1 = NULL;
     int i4, i3, i2;
 
     domain_pause(d);
@@ -434,6 +434,16 @@ int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc)
  out:
     paging_unlock(d);
     domain_unpause(d);
+
+    if ( l1 )
+        unmap_domain_page(l1);
+    if ( l2 )
+        unmap_domain_page(l2);
+    if ( l3 )
+        unmap_domain_page(l3);
+    if ( l4 )
+        unmap_domain_page(l4);
+
     return rv;
 }