From 1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 24 Sep 2003 21:49:20 +0000 Subject: [PATCH] bitkeeper revision 1.460 (3f721160CQuzVfl_qVkHJLnLn6yY1A) ldt.c: Xenolinux modify_ldt syscall now silently clamps the segment limit to a safe value. This is needed for brainded new linuxthreads versions which specify a 4GB segment limit. --- xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c b/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c index ca89b694bd..28ae39fd60 100644 --- a/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c +++ b/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c @@ -68,7 +68,7 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) { struct mm_struct * mm = current->mm; __u32 entry_1, entry_2, *lp; - unsigned long phys_lp; + unsigned long phys_lp, max_limit; int error; struct modify_ldt_ldt_s ldt_info; @@ -89,6 +89,13 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) goto out; } + /* + * This makes our tests for overlap with Xen space easier. There's no good + * reason to have a user segment starting this high anyway. + */ + if (ldt_info.base_addr >= PAGE_OFFSET) + goto out; + down_write(&mm->mmap_sem); if (!mm->context.segments) { void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); @@ -122,6 +129,13 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) } } + max_limit = HYPERVISOR_VIRT_START - ldt_info.base_addr; + if ( ldt_info.limit_in_pages ) + max_limit >>= PAGE_SHIFT; + max_limit--; + if ( (ldt_info.limit & 0xfffff) > (max_limit & 0xfffff) ) + ldt_info.limit = max_limit; + entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | (ldt_info.limit & 0x0ffff); entry_2 = (ldt_info.base_addr & 0xff000000) | -- 2.30.2