[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/debugger: use copy_to/from_guest() in dbg_rw_guest_mem()
commit 229492e210ae86e35f4af0cfb3f2b98e8e946e04 Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Wed Jun 3 09:27:09 2015 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Jun 3 09:27:09 2015 +0200 x86/debugger: use copy_to/from_guest() in dbg_rw_guest_mem() Using gdbsx on Broadwell systems suffers a SMAP violation because dbg_rw_guest_mem() uses memcpy() with a userspace pointer. The functions dbg_rw_mem() and dbg_rw_guest_mem() have been updated to pass 'void * __user' pointers which indicates their nature clearly. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/debug.c | 45 +++++++++++++++++++++++---------------- xen/arch/x86/domctl.c | 14 ++++++------ xen/include/asm-x86/debugger.h | 7 ++--- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/xen/arch/x86/debug.c b/xen/arch/x86/debug.c index 435bd40..801dcf2 100644 --- a/xen/arch/x86/debug.c +++ b/xen/arch/x86/debug.c @@ -41,6 +41,9 @@ #define DBGP2(...) ((void)0) #endif +typedef unsigned long dbgva_t; +typedef unsigned char dbgbyte_t; + /* Returns: mfn for the given (hvm guest) vaddr */ static unsigned long dbg_hvm_va2mfn(dbgva_t vaddr, struct domain *dp, int toaddr, @@ -154,13 +157,14 @@ dbg_pv_va2mfn(dbgva_t vaddr, struct domain *dp, uint64_t pgd3val) } /* Returns: number of bytes remaining to be copied */ -static int -dbg_rw_guest_mem(dbgva_t addr, dbgbyte_t *buf, int len, struct domain *dp, - int toaddr, uint64_t pgd3) +unsigned int dbg_rw_guest_mem(struct domain *dp, void * __user gaddr, + void * __user buf, unsigned int len, + bool_t toaddr, uint64_t pgd3) { while ( len > 0 ) { char *va; + unsigned long addr = (unsigned long)gaddr; unsigned long mfn, gfn = INVALID_GFN, pagecnt; pagecnt = min_t(long, PAGE_SIZE - (addr & ~PAGE_MASK), len); @@ -176,12 +180,12 @@ dbg_rw_guest_mem(dbgva_t addr, dbgbyte_t *buf, int len, struct domain *dp, if ( toaddr ) { - memcpy(va, buf, pagecnt); /* va = buf */ + copy_from_user(va, buf, pagecnt); /* va = buf */ paging_mark_dirty(dp, mfn); } else { - memcpy(buf, va, pagecnt); /* buf = va */ + copy_to_user(buf, va, pagecnt); /* buf = va */ } unmap_domain_page(va); @@ -203,27 +207,30 @@ dbg_rw_guest_mem(dbgva_t addr, dbgbyte_t *buf, int len, struct domain *dp, * pgd3: value of init_mm.pgd[3] in guest. see above. * Returns: number of bytes remaining to be copied. */ -int -dbg_rw_mem(dbgva_t addr, dbgbyte_t *buf, int len, domid_t domid, int toaddr, - uint64_t pgd3) +unsigned int dbg_rw_mem(void * __user addr, void * __user buf, + unsigned int len, domid_t domid, bool_t toaddr, + uint64_t pgd3) { - struct domain *dp = get_domain_by_id(domid); - int hyp = (domid == DOMID_IDLE); + DBGP2("gmem:addr:%lx buf:%p len:$%u domid:%d toaddr:%x\n", + addr, buf, len, domid, toaddr); - DBGP2("gmem:addr:%lx buf:%p len:$%d domid:%x toaddr:%x dp:%p\n", - addr, buf, len, domid, toaddr, dp); - if ( hyp ) + if ( domid == DOMID_IDLE ) { if ( toaddr ) - len = __copy_to_user((void *)addr, buf, len); + len = __copy_to_user(addr, buf, len); else - len = __copy_from_user(buf, (void *)addr, len); + len = __copy_from_user(buf, addr, len); } - else if ( dp ) + else { - if ( !dp->is_dying ) /* make sure guest is still there */ - len= dbg_rw_guest_mem(addr, buf, len, dp, toaddr, pgd3); - put_domain(dp); + struct domain *d = get_domain_by_id(domid); + + if ( d ) + { + if ( !d->is_dying ) + len = dbg_rw_guest_mem(d, addr, buf, len, toaddr, pgd3); + put_domain(d); + } } DBGP2("gmem:exit:len:$%d\n", len); diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index e9f76d0..1d3854f 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -37,14 +37,14 @@ #include <asm/debugger.h> #include <asm/psr.h> -static int gdbsx_guest_mem_io( - domid_t domid, struct xen_domctl_gdbsx_memio *iop) +static int gdbsx_guest_mem_io(domid_t domid, struct xen_domctl_gdbsx_memio *iop) { - ulong l_uva = (ulong)iop->uva; - iop->remain = dbg_rw_mem( - (dbgva_t)iop->gva, (dbgbyte_t *)l_uva, iop->len, domid, - iop->gwr, iop->pgd3val); - return (iop->remain ? -EFAULT : 0); + void * __user gva = (void *)iop->gva, * __user uva = (void *)iop->uva; + + iop->remain = dbg_rw_mem(gva, uva, iop->len, domid, + !!iop->gwr, iop->pgd3val); + + return iop->remain ? -EFAULT : 0; } #define MAX_IOPORTS 0x10000 diff --git a/xen/include/asm-x86/debugger.h b/xen/include/asm-x86/debugger.h index 0408bec..33f4700 100644 --- a/xen/include/asm-x86/debugger.h +++ b/xen/include/asm-x86/debugger.h @@ -82,9 +82,8 @@ static inline int debugger_trap_entry( return 0; } -typedef unsigned long dbgva_t; -typedef unsigned char dbgbyte_t; -extern int dbg_rw_mem(dbgva_t addr, dbgbyte_t *buf, int len, - domid_t domid, int toaddr, uint64_t pgd3); +unsigned int dbg_rw_mem(void * __user addr, void * __user buf, + unsigned int len, domid_t domid, bool_t toaddr, + uint64_t pgd3); #endif /* __X86_DEBUGGER_H__ */ -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |