diff options
-rw-r--r-- | xen/common/compat/grant_table.c | 8 | ||||
-rw-r--r-- | xen/common/compat/memory.c | 13 | ||||
-rw-r--r-- | xen/common/grant_table.c | 6 | ||||
-rw-r--r-- | xen/common/memory.c | 19 |
4 files changed, 32 insertions, 14 deletions
diff --git a/xen/common/compat/grant_table.c b/xen/common/compat/grant_table.c index a6e8814770..38f3b37c9b 100644 --- a/xen/common/compat/grant_table.c +++ b/xen/common/compat/grant_table.c @@ -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) diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c index a49f51b7fb..9e0192590d 100644 --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -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; } diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 716a8ceee6..6b10b6686b 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -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: diff --git a/xen/common/memory.c b/xen/common/memory.c index a88348f802..b7fdd77c0f 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -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)) ); } |