diff options
author | neel <neel@FreeBSD.org> | 2015-01-19 06:51:04 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2015-01-19 06:51:04 +0000 |
commit | 9d0b530c897c5323dd868e5afccf90a6b0c23b6e (patch) | |
tree | ec0e6478798b2f3e8ba401635c575d542ef3be88 /lib/libvmmapi | |
parent | 63c8385f8bbc4fb18ce8d54745e5c79829d532b5 (diff) | |
download | FreeBSD-src-9d0b530c897c5323dd868e5afccf90a6b0c23b6e.zip FreeBSD-src-9d0b530c897c5323dd868e5afccf90a6b0c23b6e.tar.gz |
Fix a bug in libvmmapi 'vm_copy_setup()' where it would return success even if
the 'gpa' was in the guest MMIO region. This would manifest as a segmentation
fault in 'vm_map_copyin()' or 'vm_map_copyout()' because 'vm_map_gpa()' would
return NULL for this 'gpa'.
Fix this by calling 'vm_map_gpa()' in 'vm_copy_setup' and returning a failure
if the 'gpa' cannot be mapped. This matches the behavior of 'vm_copy_setup()'
in vmm.ko.
MFC after: 1 week
Diffstat (limited to 'lib/libvmmapi')
-rw-r--r-- | lib/libvmmapi/vmmapi.c | 22 | ||||
-rw-r--r-- | lib/libvmmapi/vmmapi.h | 2 |
2 files changed, 17 insertions, 7 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 5660f3b..9828876 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -987,6 +987,7 @@ int vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt) { + void *va; uint64_t gpa; int error, fault, i, n, off; @@ -1006,7 +1007,11 @@ vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, off = gpa & PAGE_MASK; n = min(len, PAGE_SIZE - off); - iov->iov_base = (void *)gpa; + va = vm_map_gpa(ctx, gpa, n); + if (va == NULL) + return (-1); + + iov->iov_base = va; iov->iov_len = n; iov++; iovcnt--; @@ -1018,19 +1023,24 @@ vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, } void +vm_copy_teardown(struct vmctx *ctx, int vcpu, struct iovec *iov, int iovcnt) +{ + + return; +} + +void vm_copyin(struct vmctx *ctx, int vcpu, struct iovec *iov, void *vp, size_t len) { const char *src; char *dst; - uint64_t gpa; size_t n; dst = vp; while (len) { assert(iov->iov_len); - gpa = (uint64_t)iov->iov_base; n = min(len, iov->iov_len); - src = vm_map_gpa(ctx, gpa, n); + src = iov->iov_base; bcopy(src, dst, n); iov++; @@ -1045,15 +1055,13 @@ vm_copyout(struct vmctx *ctx, int vcpu, const void *vp, struct iovec *iov, { const char *src; char *dst; - uint64_t gpa; size_t n; src = vp; while (len) { assert(iov->iov_len); - gpa = (uint64_t)iov->iov_base; n = min(len, iov->iov_len); - dst = vm_map_gpa(ctx, gpa, n); + dst = iov->iov_base; bcopy(src, dst, n); iov++; diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h index 8634762..06b2930 100644 --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -137,6 +137,8 @@ void vm_copyin(struct vmctx *ctx, int vcpu, struct iovec *guest_iov, void *host_dst, size_t len); void vm_copyout(struct vmctx *ctx, int vcpu, const void *host_src, struct iovec *guest_iov, size_t len); +void vm_copy_teardown(struct vmctx *ctx, int vcpu, struct iovec *iov, + int iovcnt); /* RTC */ int vm_rtc_write(struct vmctx *ctx, int offset, uint8_t value); |