aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-09-24 21:49:20 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-09-24 21:49:20 +0000
commit1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c (patch)
tree2a3bc55a3ebaa5964e144b516457442712e4022d
parent156bcf860cf42b43660850f1ec174c435681f7f2 (diff)
downloadxen-1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c.tar.gz
xen-1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c.tar.bz2
xen-1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c.zip
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.
-rw-r--r--xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c16
1 files changed, 15 insertions, 1 deletions
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) |