patch-2.0.28 linux/arch/i386/kernel/ldt.c
Next file: linux/arch/i386/kernel/signal.c
Previous file: linux/arch/i386/kernel/entry.S
Back to the patch index
Back to the overall index
- Lines: 56
- Date:
Wed Dec 11 16:41:01 1996
- Orig file:
v2.0.27/linux/arch/i386/kernel/ldt.c
- Orig date:
Thu Mar 7 16:24:45 1996
diff -u --recursive --new-file v2.0.27/linux/arch/i386/kernel/ldt.c linux/arch/i386/kernel/ldt.c
@@ -59,7 +59,7 @@
return (last >= first && last < TASK_SIZE);
}
-static int write_ldt(void * ptr, unsigned long bytecount)
+static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
{
struct modify_ldt_ldt_s ldt_info;
unsigned long *lp;
@@ -73,10 +73,10 @@
memcpy_fromfs(&ldt_info, ptr, sizeof(ldt_info));
- if (ldt_info.contents == 3 || ldt_info.entry_number >= LDT_ENTRIES)
+ if ((ldt_info.contents == 3 && (oldmode || ldt_info.seg_not_present == 0)) || ldt_info.entry_number >= LDT_ENTRIES)
return -EINVAL;
- if (!limits_ok(&ldt_info))
+ if (!limits_ok(&ldt_info) && (oldmode || ldt_info.seg_not_present == 0))
return -EINVAL;
if (!current->ldt) {
@@ -93,7 +93,14 @@
lp = (unsigned long *) ¤t->ldt[ldt_info.entry_number];
/* Allow LDTs to be cleared by the user. */
- if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0
+ && (oldmode ||
+ ( ldt_info.contents == 0
+ && ldt_info.read_exec_only == 1
+ && ldt_info.seg_32bit == 0
+ && ldt_info.limit_in_pages == 0
+ && ldt_info.seg_not_present == 1
+ && ldt_info.useable == 0 )) ) {
*lp = 0;
*(lp+1) = 0;
return 0;
@@ -109,6 +116,7 @@
(ldt_info.limit_in_pages << 23) |
((ldt_info.seg_not_present ^1) << 15) |
0x7000;
+ if (!oldmode) *(lp+1) |= (ldt_info.useable << 20);
return 0;
}
@@ -117,6 +125,8 @@
if (func == 0)
return read_ldt(ptr, bytecount);
if (func == 1)
- return write_ldt(ptr, bytecount);
+ return write_ldt(ptr, bytecount, 1);
+ if (func == 0x11)
+ return write_ldt(ptr, bytecount, 0);
return -ENOSYS;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov