summaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/start_up.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/start_up.c')
-rw-r--r--arch/um/os-Linux/start_up.c75
1 files changed, 70 insertions, 5 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b99ab41..553a09c 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -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)
+{
+#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("Checking for /proc/mm...");
+ 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
OpenPOWER on IntegriCloud