diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-09-11 14:17:59 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-09-11 14:17:59 +0200 |
commit | 6c777beb83875f7e0cc77ca357025608a56b3560 (patch) | |
tree | 4bc1e833ecfd384de6a067a0bcbd154d8d98fa5d /xen/common/tmem.c | |
parent | 09d39e0108811d6bfe1ab7f819b951ea0b1611d7 (diff) | |
download | xen-6c777beb83875f7e0cc77ca357025608a56b3560.tar.gz xen-6c777beb83875f7e0cc77ca357025608a56b3560.tar.bz2 xen-6c777beb83875f7e0cc77ca357025608a56b3560.zip |
tmem: detect arithmetic overflow in tmh_copy_{from,to}_client()
This implies adjusting callers to deal with errors other than -EFAULT
and removing some comments which would otherwise become stale.
Reported-by: Tim Deegan <tim@xen.org>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com>
Diffstat (limited to 'xen/common/tmem.c')
-rw-r--r-- | xen/common/tmem.c | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/xen/common/tmem.c b/xen/common/tmem.c index e6c3b38f89..b1d0017e47 100644 --- a/xen/common/tmem.c +++ b/xen/common/tmem.c @@ -1535,7 +1535,7 @@ copy_uncompressed: /* tmh_copy_from_client properly handles len==0 and offsets != 0 */ ret = tmh_copy_from_client(pgp->pfp, cmfn, tmem_offset, pfn_offset, len, tmh_cli_buf_null); - if ( ret == -EFAULT ) + if ( ret < 0 ) goto bad_copy; if ( tmh_dedup_enabled() && !is_persistent(pool) ) { @@ -1556,9 +1556,7 @@ done: return 1; bad_copy: - /* this should only happen if the client passed a bad mfn */ failed_copies++; - ret = -EFAULT; goto cleanup; failed_dup: @@ -1662,7 +1660,7 @@ copy_uncompressed: /* tmh_copy_from_client properly handles len==0 (TMEM_NEW_PAGE) */ ret = tmh_copy_from_client(pgp->pfp, cmfn, tmem_offset, pfn_offset, len, clibuf); - if ( ret == -EFAULT ) + if ( ret < 0 ) goto bad_copy; if ( tmh_dedup_enabled() && !is_persistent(pool) ) { @@ -1702,8 +1700,6 @@ insert_page: return 1; bad_copy: - /* this should only happen if the client passed a bad mfn */ - ret = -EFAULT; failed_copies++; delete_and_free: @@ -1737,7 +1733,7 @@ static NOINLINE int do_tmem_get(pool_t *pool, OID *oidp, uint32_t index, pgp_t *pgp; client_t *client = pool->client; DECL_LOCAL_CYC_COUNTER(decompress); - int rc = -EFAULT; + int rc; if ( !_atomic_read(pool->pgp_count) ) return -EEMPTY; @@ -1761,20 +1757,20 @@ static NOINLINE int do_tmem_get(pool_t *pool, OID *oidp, uint32_t index, ASSERT(pgp->size != -1); if ( tmh_dedup_enabled() && !is_persistent(pool) && pgp->firstbyte != NOT_SHAREABLE ) - { rc = pcd_copy_to_client(cmfn, pgp); - if ( rc <= 0 ) - goto bad_copy; - } else if ( pgp->size != 0 ) { + else if ( pgp->size != 0 ) + { START_CYC_COUNTER(decompress); rc = tmh_decompress_to_client(cmfn, pgp->cdata, pgp->size, clibuf); - if ( rc <= 0 ) - goto bad_copy; END_CYC_COUNTER(decompress); - } else if ( tmh_copy_to_client(cmfn, pgp->pfp, tmem_offset, - pfn_offset, len, clibuf) == -EFAULT) + } + else + rc = tmh_copy_to_client(cmfn, pgp->pfp, tmem_offset, + pfn_offset, len, clibuf); + if ( rc <= 0 ) goto bad_copy; + if ( is_ephemeral(pool) ) { if ( is_private(pool) ) @@ -1811,7 +1807,6 @@ static NOINLINE int do_tmem_get(pool_t *pool, OID *oidp, uint32_t index, return 1; bad_copy: - /* this should only happen if the client passed a bad mfn */ failed_copies++; return rc; } |