[PATCH] uml: maintain own LDT entries

Patch imlements full LDT handling in SKAS:
 * UML holds it's own LDT table, used to deliver data on
   modify_ldt(READ)
 * UML disables the default_ldt, inherited from the host (SKAS3)
   or resets LDT entries, set by host's clib and inherited in
   SKAS0
 * A new global variable skas_needs_stub is inserted, that
   can be used to decide, whether stub-pages must be supported
   or not.
 * Uses the syscall-stub to replace missing PTRACE_LDT (therefore,
   write_ldt_entry needs to be modified)

Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Bodo Stroesser
2005-11-07 00:58:55 -08:00
committed by Linus Torvalds
parent e763b793f7
commit 858259cf7d
13 changed files with 724 additions and 141 deletions

View File

@@ -135,7 +135,9 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
}
int ptrace_faultinfo = 1;
int ptrace_ldt = 1;
int proc_mm = 1;
int skas_needs_stub = 0;
static int __init skas0_cmd_param(char *str, int* add)
{
@@ -352,14 +354,26 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
" it. To support PTRACE_FAULTINFO, the host needs to be patched\n"
" using the current skas3 patch.\n\n");
static int __init noptraceldt_cmd_param(char *str, int* add)
{
ptrace_ldt = 0;
return 0;
}
__uml_setup("noptraceldt", noptraceldt_cmd_param,
"noptraceldt\n"
" Turns off usage of PTRACE_LDT, even if host supports it.\n"
" To support PTRACE_LDT, the host needs to be patched using\n"
" the current skas3 patch.\n\n");
#ifdef UML_CONFIG_MODE_SKAS
static inline void check_skas3_ptrace_support(void)
static inline void check_skas3_ptrace_faultinfo(void)
{
struct ptrace_faultinfo fi;
void *stack;
int pid, n;
printf("Checking for the skas3 patch in the host...");
printf(" - PTRACE_FAULTINFO...");
pid = start_ptraced_child(&stack);
n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
@@ -381,9 +395,49 @@ static inline void check_skas3_ptrace_support(void)
stop_ptraced_child(pid, stack, 1, 1);
}
int can_do_skas(void)
static inline void check_skas3_ptrace_ldt(void)
{
printf("Checking for /proc/mm...");
#ifdef PTRACE_LDT
void *stack;
int pid, n;
unsigned char ldtbuf[40];
struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
.func = 2, /* read default ldt */
.ptr = ldtbuf,
.bytecount = sizeof(ldtbuf)};
printf(" - PTRACE_LDT...");
pid = start_ptraced_child(&stack);
n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
if (n < 0) {
if(errno == EIO)
printf("not found\n");
else {
perror("not found");
}
ptrace_ldt = 0;
}
else {
if(ptrace_ldt)
printf("found\n");
else
printf("found, but use is disabled\n");
}
stop_ptraced_child(pid, stack, 1, 1);
#else
/* PTRACE_LDT might be disabled via cmdline option.
* We want to override this, else we might use the stub
* without real need
*/
ptrace_ldt = 1;
#endif
}
static inline void check_skas3_proc_mm(void)
{
printf(" - /proc/mm...");
if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
proc_mm = 0;
printf("not found\n");
@@ -394,8 +448,19 @@ int can_do_skas(void)
else
printf("found\n");
}
}
int can_do_skas(void)
{
printf("Checking for the skas3 patch in the host:\n");
check_skas3_proc_mm();
check_skas3_ptrace_faultinfo();
check_skas3_ptrace_ldt();
if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
skas_needs_stub = 1;
check_skas3_ptrace_support();
return 1;
}
#else