From: Jeff Dike <jdike@addtoit.com>
To: UML-user <user-mode-linux-user@lists.sourceforge.net>,
uml-devel <user-mode-linux-devel@lists.sourceforge.net>
Subject: [SPAM] [uml-devel] [RFC PATCH 6/10] SKAS4 - Guest support for using PTRACE_GETSIGINFO
Date: Wed, 23 Jan 2008 12:12:29 -0500 [thread overview]
Message-ID: <20080123171229.GA7629@c2.user-mode-linux.org> (raw)
The nastiness in arch/um/include/siginfo_segv.h is defining the new
siginfo_t structure in place of the old one, which requires using CPP
to rename the old one out of the way.
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
index b073f8a..d6cbb4f 100644
--- a/arch/um/include/skas/skas.h
+++ b/arch/um/include/skas/skas.h
@@ -8,6 +8,8 @@
#include "sysdep/ptrace.h"
+extern int have_siginfo_segv;
+
extern int userspace_pid[];
extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
extern int skas_needs_stub;
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index e8b7a97..82a0780 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -3,6 +3,9 @@
* Licensed under the GPL
*/
+/* Include this first, before anything else includes <signal.h> */
+#include "siginfo_segv.h"
+
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
@@ -91,11 +94,23 @@ bad_wait:
extern unsigned long current_stub_stack(void);
+#ifndef PTRACE_GETSIGINFO
+#define PTRACE_GETSIGINFO 0x4202
+#endif
+
void get_skas_faultinfo(int pid, struct faultinfo * fi)
{
+ siginfo_t si;
int err;
- if (ptrace_faultinfo) {
+ if(have_siginfo_segv){
+ err = ptrace(PTRACE_GETSIGINFO, pid, 0, &si);
+ if(err)
+ printk("PTRACE_GETSIGINFO failed, err = %d\n", errno);
+
+ GET_FAULTINFO_FROM_SI(*fi, si);
+ }
+ else if (ptrace_faultinfo) {
err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
if (err)
panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 2576d70..0e0f738 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -3,6 +3,9 @@
* Licensed under the GPL
*/
+/* Include this first, before anything else includes <signal.h> */
+#include "siginfo_segv.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -25,6 +28,7 @@
#include "registers.h"
#include "skas.h"
#include "skas_ptrace.h"
+#include "sysdep/sigcontext.h"
static int ptrace_child(void)
{
@@ -154,6 +158,9 @@ static int disable_proc_mm;
int have_switch_mm;
static int disable_switch_mm;
+int have_siginfo_segv;
+static int disable_siginfo_segv;
+
int skas_needs_stub;
static int __init skas0_cmd_param(char *str, int* add)
@@ -162,6 +169,7 @@ static int __init skas0_cmd_param(char *str, int* add)
disable_ptrace_ldt = 1;
disable_proc_mm = 1;
disable_switch_mm = 1;
+ disable_siginfo_segv = 1;
return 0;
}
@@ -475,6 +483,137 @@ static inline void check_skas3_proc_mm(void)
}
}
+static void *fault_address;
+
+static int check_fault_info(struct faultinfo *fi)
+{
+ return (FAULT_ADDRESS(*fi) == (unsigned long) fault_address) &&
+ FAULT_WRITE(*fi) && SEGV_IS_FIXABLE(fi);
+}
+
+static jmp_buf siginfo_buf;
+
+static void segv_handler(int sig, siginfo_t *si, void *foo)
+{
+ struct faultinfo fi;
+ int n;
+
+ GET_FAULTINFO_FROM_SI(fi, *si);
+ n = check_fault_info(&fi) ? 1 : 2;
+ longjmp(siginfo_buf, n);
+}
+
+static int fault(void)
+{
+ struct sigaction sa, old;
+ int err, n;
+
+ /*
+ * The cast is needed because the CPP manipulations of
+ * siginfo_t resulted in sa_sigaction having an old_siginfo_t
+ * parameter.
+ */
+ sa.sa_sigaction = (void (*)(int, old_siginfo_t *, void *)) segv_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO | SA_NODEFER;
+
+ err = sigaction(SIGSEGV, &sa, &old);
+ if (err)
+ fatal_perror("sigaction");
+
+ /*
+ * Provide a guaranteed invalid address by mapping a page into
+ * a hole in the address space and then unmapping it.
+ */
+ fault_address = mmap(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (fault_address == MAP_FAILED)
+ fatal_perror("mmap failed");
+
+ if (munmap(fault_address, UM_KERN_PAGE_SIZE) < 0)
+ fatal_perror("munmap failed");
+
+ n = setjmp(siginfo_buf);
+ if (n == 0)
+ *((unsigned long *) fault_address) = 0;
+
+ err = sigaction(SIGSEGV, &old, NULL);
+
+ return n;
+}
+
+static int __init nogetsiginfo_cmd_param(char *str, int *add)
+{
+ disable_siginfo_segv = 1;
+ return 0;
+}
+
+__uml_setup("nogetsiginfo", nogetsiginfo_cmd_param,
+"nogetsiginfo\n"
+" Turns off usage of PTRACE_GETSIGINFO to read page fault information\n"
+" from a child process, even if the host supports it.\n\n");
+
+#ifndef PTRACE_GETSIGINFO
+#define PTRACE_GETSIGINFO 0x4202
+#endif
+
+static int check_siginfo(void)
+{
+ siginfo_t si;
+ struct faultinfo fi;
+ int ok, pid, err, status;
+
+ non_fatal("\tFull CPU fault information in siginfo_t ... ");
+ ok = fault();
+ if (ok)
+ non_fatal("OK\n");
+ else {
+ non_fatal("Failed\n");
+ return 0;
+ }
+
+ non_fatal("\tFull CPU fault information in PTRACE_GETSIGINFO ... ");
+
+ pid = fork();
+ if (pid < 0)
+ fatal_perror("fork failed");
+ else if (pid == 0) {
+ ptrace(PTRACE_TRACEME, 0, 0, 0);
+ fault();
+ exit(1);
+ }
+
+ while(1){
+ err = waitpid(pid, &status, WUNTRACED);
+ if (err < 0)
+ fatal_perror("wait failed");
+
+ if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGSEGV))
+ break;
+ }
+
+ err = ptrace(PTRACE_GETSIGINFO, pid, 0, &si);
+ if (err < 0)
+ fatal_perror("PTRACE_GETSIGINFO failed");
+
+ ptrace(PTRACE_KILL, pid, 0, 0);
+
+ GET_FAULTINFO_FROM_SI(fi, si);
+ ok = check_fault_info(&fi);
+ if (ok)
+ non_fatal("OK\n");
+ else
+ non_fatal("Failed\n");
+
+ if (disable_siginfo_segv)
+ non_fatal("Extended PTRACE_GETSIGINFO disabled on command "
+ "line");
+ else
+ have_siginfo_segv = 1;
+
+ return ok;
+}
+
void can_do_skas(void)
{
non_fatal("Checking for the skas3 patch in the host:\n");
@@ -482,6 +621,7 @@ void can_do_skas(void)
check_skas3_proc_mm();
check_skas3_ptrace_faultinfo();
check_skas3_ptrace_ldt();
+ check_siginfo();
if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
skas_needs_stub = 1;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
reply other threads:[~2008-01-23 17:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080123171229.GA7629@c2.user-mode-linux.org \
--to=jdike@addtoit.com \
--cc=user-mode-linux-devel@lists.sourceforge.net \
--cc=user-mode-linux-user@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.