]> xenbits.xensource.com Git - people/aperard/xen-arm.git/commitdiff
tighten guest memory accesses
authorJan Beulich <jbeulich@suse.com>
Thu, 6 Dec 2012 13:20:15 +0000 (14:20 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 6 Dec 2012 13:20:15 +0000 (14:20 +0100)
Failure should always be detected and handled.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
xen/common/compat/grant_table.c
xen/common/compat/memory.c
xen/common/grant_table.c
xen/common/memory.c

index a6e8814770dad5362eb4ebaf24e7fa2b055c07d0..38f3b37c9b173c4cffe58574197b6f29cf1624a6 100644 (file)
@@ -173,7 +173,9 @@ int compat_grant_table_op(unsigned int cmd,
                         for ( i = 0; i < (_s_)->nr_frames; ++i ) \
                         { \
                             unsigned int frame = (_s_)->frame_list.p[i]; \
-                            (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \
+                            if ( __copy_to_compat_offset((_d_)->frame_list, \
+                                                         i, &frame, 1) ) \
+                                (_s_)->status = GNTST_bad_virt_addr; \
                         } \
                     } \
                 } while (0)
@@ -310,7 +312,9 @@ int compat_grant_table_op(unsigned int cmd,
                         for ( i = 0; i < (_s_)->nr_frames; ++i ) \
                         { \
                             uint64_t frame = (_s_)->frame_list.p[i]; \
-                            (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \
+                            if ( __copy_to_compat_offset((_d_)->frame_list, \
+                                                         i, &frame, 1) ) \
+                                (_s_)->status = GNTST_bad_virt_addr; \
                         } \
                     } \
                 } while (0)
index a49f51b7fb35bd0b8bf65cba8756681349560ba3..9e0192590dc2ab1bb962b45cd9c54521d61659a7 100644 (file)
@@ -283,18 +283,25 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat)
                 compat_pfn_t pfn = nat.xchg->out.extent_start.p[start_extent];
 
                 BUG_ON(pfn != nat.xchg->out.extent_start.p[start_extent]);
-                /* Note that we ignore errors accessing the output extent list. */
-                __copy_to_compat_offset(cmp.xchg.out.extent_start, start_extent, &pfn, 1);
+                if ( __copy_to_compat_offset(cmp.xchg.out.extent_start,
+                                             start_extent, &pfn, 1) )
+                {
+                    rc = -EFAULT;
+                    break;
+                }
             }
 
             cmp.xchg.nr_exchanged = nat.xchg->nr_exchanged;
             if ( copy_field_to_guest(guest_handle_cast(compat, compat_memory_exchange_t),
                                      &cmp.xchg, nr_exchanged) )
+                rc = -EFAULT;
+
+            if ( rc < 0 )
             {
                 if ( split < 0 )
                     /* Cannot cancel the continuation... */
                     domain_crash(current->domain);
-                return -EFAULT;
+                return rc;
             }
             break;
         }
index 716a8ceee609f0c55931b454121b4a0d81c71ff4..6b10b6686b8a2dca794cdc57f21f062594238b4c 100644 (file)
@@ -1347,6 +1347,9 @@ gnttab_setup_table(
         goto out1;
     }
 
+    if ( !guest_handle_okay(op.frame_list, op.nr_frames) )
+        return -EFAULT;
+
     d = gt_lock_target_domain_by_id(op.dom);
     if ( IS_ERR(d) )
     {
@@ -1384,7 +1387,8 @@ gnttab_setup_table(
         gmfn = gnttab_shared_gmfn(d, gt, i);
         /* Grant tables cannot be shared */
         BUG_ON(SHARED_M2P(gmfn));
-        (void)copy_to_guest_offset(op.frame_list, i, &gmfn, 1);
+        if ( __copy_to_guest_offset(op.frame_list, i, &gmfn, 1) )
+            op.status = GNTST_bad_virt_addr;
     }
 
  out3:
index a88348f802ac84ce7f0ff32fa80a543dea1c7551..b7fdd77c0f4555e1ec0dc91945c00c9c6ab93aeb 100644 (file)
@@ -445,8 +445,7 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg)
         }
 
         /* Assign each output page to the domain. */
-        j = 0;
-        while ( (page = page_list_remove_head(&out_chunk_list)) )
+        for ( j = 0; (page = page_list_remove_head(&out_chunk_list)); ++j )
         {
             if ( assign_pages(d, page, exch.out.extent_order,
                               MEMF_no_refcount) )
@@ -477,9 +476,12 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg)
                 goto dying;
             }
 
-            /* Note that we ignore errors accessing the output extent list. */
-            (void)__copy_from_guest_offset(
-                &gpfn, exch.out.extent_start, (i<<out_chunk_order)+j, 1);
+            if ( __copy_from_guest_offset(&gpfn, exch.out.extent_start,
+                                          (i << out_chunk_order) + j, 1) )
+            {
+                rc = -EFAULT;
+                continue;
+            }
 
             mfn = page_to_mfn(page);
             guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
@@ -488,10 +490,11 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg)
             {
                 for ( k = 0; k < (1UL << exch.out.extent_order); k++ )
                     set_gpfn_from_mfn(mfn + k, gpfn + k);
-                (void)__copy_to_guest_offset(
-                    exch.out.extent_start, (i<<out_chunk_order)+j, &mfn, 1);
+                if ( __copy_to_guest_offset(exch.out.extent_start,
+                                            (i << out_chunk_order) + j,
+                                            &mfn, 1) )
+                    rc = -EFAULT;
             }
-            j++;
         }
         BUG_ON( !(d->is_dying) && (j != (1UL << out_chunk_order)) );
     }