[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/PV: consolidate LDT checks
Consolidate all hypercall time checking into a single helper function, checking only static properties. The dynamic properties are already taken care of by the __addr_ok() check in guest_get_eff_kern_l1e(), used by pv_map_ldt_shadow_page(), in a formally more "precise" manner (accounting for the offset into the table). Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1081,7 +1081,6 @@ int arch_set_info_guest( if ( !is_canonical_address(c.nat->user_regs.rip) || !is_canonical_address(c.nat->user_regs.rsp) || !is_canonical_address(c.nat->kernel_sp) || - (c.nat->ldt_ents && !is_canonical_address(c.nat->ldt_base)) || !is_canonical_address(c.nat->fs_base) || !is_canonical_address(c.nat->gs_base_kernel) || !is_canonical_address(c.nat->gs_base_user) || @@ -1100,9 +1099,6 @@ int arch_set_info_guest( return -EINVAL; fixup_guest_code_selector(d, c.nat->trap_ctxt[i].cs); } - - if ( !__addr_ok(c.nat->ldt_base) ) - return -EINVAL; } #ifdef CONFIG_COMPAT else @@ -1119,8 +1115,7 @@ int arch_set_info_guest( #endif /* LDT safety checks. */ - if ( ((c(ldt_base) & (PAGE_SIZE - 1)) != 0) || - (c(ldt_ents) > 8192) ) + if ( !pv_is_valid_ldt(c(ldt_base), c(ldt_ents)) ) return -EINVAL; v->arch.pv.vgc_flags = flags; --- a/xen/arch/x86/include/asm/pv/mm.h +++ b/xen/arch/x86/include/asm/pv/mm.h @@ -46,4 +46,14 @@ static inline bool pv_destroy_ldt(struct #endif +static inline bool pv_is_valid_ldt(unsigned long base, unsigned int ents) +{ + if ( !ents ) + return true; + + return !(base & (PAGE_SIZE - 1)) && ents <= 8192 && + is_canonical_address(base) && + is_canonical_address(base + ents * 8 - 1); +} + #endif /* __X86_PV_MM_H__ */ --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3800,8 +3800,7 @@ long do_mmuext_op( rc = -EPERM; else if ( paging_mode_external(currd) ) rc = -EINVAL; - else if ( (ents > 8192) || - (ents && ((ptr & (PAGE_SIZE - 1)) || !__addr_ok(ptr))) ) + else if ( !pv_is_valid_ldt(ptr, ents) ) { gdprintk(XENLOG_WARNING, "Bad args to SET_LDT: ptr=%lx, ents=%x\n", ptr, ents);
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |