aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-12-06 14:20:15 +0100
committerJan Beulich <jbeulich@suse.com>2012-12-06 14:20:15 +0100
commit519b2f205a6e85927816b66e1096d6802ee47f1b (patch)
tree9c050cb3dad6ad5d7051fe8459ad004acd8e7964
parent8e4addea279da7430d80514828f49013979117e6 (diff)
downloadxen-519b2f205a6e85927816b66e1096d6802ee47f1b.tar.gz
xen-519b2f205a6e85927816b66e1096d6802ee47f1b.tar.bz2
xen-519b2f205a6e85927816b66e1096d6802ee47f1b.zip
tighten guest memory accesses
Failure should always be detected and handled. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
-rw-r--r--xen/common/compat/grant_table.c8
-rw-r--r--xen/common/compat/memory.c13
-rw-r--r--xen/common/grant_table.c6
-rw-r--r--xen/common/memory.c19
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)) );
}