public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/sandbox:master commit in: libsandbox/trace/linux/, /, libsandbox/wrapper-funcs/, libsandbox/, tests/
@ 2012-07-03 19:41 Mike Frysinger
  0 siblings, 0 replies; only message in thread
From: Mike Frysinger @ 2012-07-03 19:41 UTC (permalink / raw
  To: gentoo-commits

commit:     106c4cb4b1dd814fc29c56269dc964d03dadde15
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Wed Dec  7 18:18:29 2011 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Tue Jul  3 18:27:45 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/sandbox.git;a=commit;h=106c4cb4

libsandbox: add x32 ABI support

We can trace x32 when the host is x86_64 or x32, but x32 cannot trace
x86_64 due to limitations in the kernel interface -- all pointers get
truncated to 32bits.  We'll have to add external ptrace helpers in the
future to make this work, but for now, we'll just let x86_64 code run
unchecked :(.

URL: https://bugs.gentoo.org/394179
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>

---
 configure.ac                              |    2 +-
 libsandbox/libsandbox.h                   |    1 +
 libsandbox/trace.c                        |   21 ++++++++++--
 libsandbox/trace/linux/i386.c             |   10 ++++++
 libsandbox/trace/linux/x86_64.c           |   48 +++++++++++++++++++++++++++--
 libsandbox/wrapper-funcs/__wrapper_exec.c |    4 +-
 tests/script-0                            |    4 +-
 7 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index 26f6822..3bf3a8c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,7 @@ AC_ARG_ENABLE([schizo],
 SB_SCHIZO_SETTINGS="no"
 if test "x$enable_schizo" = "xyes" ; then
 	case $host_alias in
-		x86_64*linux*) SB_SCHIZO_SETTINGS="x86_64:-m64 x86:-m32";;
+		x86_64*linux*) SB_SCHIZO_SETTINGS="x86_64:-m64 x86:-m32 x32:-mx32";;
 	esac
 fi
 if test "$SB_SCHIZO_SETTINGS" != "no" ; then

diff --git a/libsandbox/libsandbox.h b/libsandbox/libsandbox.h
index 38e983d..76dd8c8 100644
--- a/libsandbox/libsandbox.h
+++ b/libsandbox/libsandbox.h
@@ -61,6 +61,7 @@ extern pid_t trace_pid;
 extern void sb_lock(void);
 extern void sb_unlock(void);
 
+bool trace_possible(const char *filename, char *const argv[], const void *data);
 void trace_main(const char *filename, char *const argv[]);
 
 /* glibc modified realpath() function */

diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index f2071e0..ea769fd 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -11,6 +11,7 @@
 
 static long _do_ptrace(enum __ptrace_request request, const char *srequest, void *addr, void *data);
 #define do_ptrace(request, addr, data) _do_ptrace(request, #request, addr, data)
+#define _trace_possible(data) true
 
 #ifdef DEBUG
 # define SBDEBUG 1
@@ -485,6 +486,16 @@ void trace_main(const char *filename, char *const argv[])
 
 #else
 
+#undef _trace_possible
+#define _trace_possible(data) false
+
+void trace_main(const char *filename, char *const argv[])
+{
+	/* trace_possible() triggers a warning for us */
+}
+
+#endif
+
 static char *flatten_args(char *const argv[])
 {
 	char *ret;
@@ -512,11 +523,13 @@ static char *flatten_args(char *const argv[])
 	return ret;
 }
 
-void trace_main(const char *filename, char *const argv[])
+bool trace_possible(const char *filename, char *const argv[], const void *data)
 {
+	if (_trace_possible(data))
+		return true;
+
 	char *args = flatten_args(argv);
-	sb_eqawarn("Static ELF: %s: %s\n", filename, args);
+	sb_eqawarn("Unable to trace static ELF: %s: %s\n", filename, args);
 	free(args);
+	return false;
 }
-
-#endif

diff --git a/libsandbox/trace/linux/i386.c b/libsandbox/trace/linux/i386.c
index f214026..d7b9eaa 100644
--- a/libsandbox/trace/linux/i386.c
+++ b/libsandbox/trace/linux/i386.c
@@ -1,3 +1,13 @@
+#undef _trace_possible
+#define _trace_possible _trace_possible
+static bool _trace_possible(const void *data)
+{
+	/* i386 can only trace i386 :( */
+	const Elf64_Ehdr *ehdr = data;
+	return (ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
+		(ehdr->e_machine == EM_386);
+}
+
 #define trace_reg_sysnum orig_eax
 #define trace_reg_ret eax
 

diff --git a/libsandbox/trace/linux/x86_64.c b/libsandbox/trace/linux/x86_64.c
index 9b7e4ea..5bd1361 100644
--- a/libsandbox/trace/linux/x86_64.c
+++ b/libsandbox/trace/linux/x86_64.c
@@ -1,3 +1,6 @@
+#undef _trace_possible
+#define _trace_possible _trace_possible
+
 #ifdef SB_SCHIZO
 
 static const struct syscall_entry syscall_table_32[] = {
@@ -12,20 +15,51 @@ static const struct syscall_entry syscall_table_64[] = {
 #undef S
 	{ SB_NR_UNDEF, SB_NR_UNDEF, NULL },
 };
+static const struct syscall_entry syscall_table_x32[] = {
+#define S(s) { SB_SYS_x32_##s, SB_NR_##s, #s },
+#include "trace_syscalls_x32.h"
+#undef S
+	{ SB_NR_UNDEF, SB_NR_UNDEF, NULL },
+};
 
 static bool pers_is_32(trace_regs *regs)
 {
 	switch (regs->cs) {
 		case 0x23: return true;
 		case 0x33: return false;
-		default:   sb_ebort("unknown x86_64 personality");
+		default:   sb_ebort("unknown x86_64 (CS) personality");
+	}
+}
+
+static bool pers_is_x32(trace_regs *regs)
+{
+	switch (regs->ds) {
+		case 0x2b: return true;
+		case 0x00: return false;
+		default:   sb_ebort("unknown x86_64 (DS) personality");
 	}
 }
 
 static const struct syscall_entry *trace_check_personality(void *vregs)
 {
 	trace_regs *regs = vregs;
-	return pers_is_32(regs) ? syscall_table_32 : syscall_table_64;
+	if (pers_is_32(regs))
+		return syscall_table_32;
+	else if (pers_is_x32(regs))
+		return syscall_table_x32;
+	else
+		return syscall_table_64;
+}
+
+static bool _trace_possible(const void *data)
+{
+	/* x86_64 can trace anything, but x32 can't trace x86_64 */
+#if defined(__x86_64__) && defined(__ILP32__)
+	const Elf64_Ehdr *ehdr = data;
+	return (ehdr->e_ident[EI_CLASS] == ELFCLASS32);
+#else
+	return true;
+#endif
 }
 
 #else
@@ -35,6 +69,13 @@ static bool pers_is_32(trace_regs *regs)
 	return false;
 }
 
+static bool _trace_possible(const void *data)
+{
+	const Elf64_Ehdr *ehdr = data;
+	return (ehdr->e_ident[EI_CLASS] == ELFCLASS64) &&
+		(ehdr->e_machine == EM_X86_64);
+}
+
 #endif
 
 #define trace_reg_sysnum orig_rax
@@ -56,6 +97,7 @@ static unsigned long trace_arg(void *vregs, int num)
 {
 	trace_regs *regs = vregs;
 	if (pers_is_32(regs))
+		/* 32bit x86 */
 		switch (num) {
 			case 1: return regs->rbx;
 			case 2: return regs->rcx;
@@ -82,7 +124,7 @@ static void trace_dump_regs(void *vregs)
 {
 	trace_regs *regs = vregs;
 	sb_printf("{ ");
-#define D(r) sb_printf(#r":%lu ", regs->r)
+#define D(r) sb_printf(#r":%"PRIu64" ", regs->r)
 	D(rax);
 	D(rdi);
 	D(rsi);

diff --git a/libsandbox/wrapper-funcs/__wrapper_exec.c b/libsandbox/wrapper-funcs/__wrapper_exec.c
index c3536c3..0ffc08a 100644
--- a/libsandbox/wrapper-funcs/__wrapper_exec.c
+++ b/libsandbox/wrapper-funcs/__wrapper_exec.c
@@ -33,7 +33,7 @@ static void sb_check_exec(const char *filename, char *const argv[])
 		return;
 	if (stat(filename, &st))
 		goto out_fd;
-	if (st.st_size < EI_NIDENT)
+	if (st.st_size < sizeof(Elf64_Ehdr))
 		goto out_fd;
 	elf = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
 	if (elf == MAP_FAILED)
@@ -65,7 +65,7 @@ static void sb_check_exec(const char *filename, char *const argv[])
 	else
 		PARSE_ELF(64);
 
-	do_trace = true;
+	do_trace = trace_possible(filename, argv, elf);
 	/* Now that we're done with stuff, clean up before forking */
 
  done:

diff --git a/tests/script-0 b/tests/script-0
index 7e6bde6..b25032f 100755
--- a/tests/script-0
+++ b/tests/script-0
@@ -1,6 +1,6 @@
 #!/bin/sh
 # shell scripts only get properly wrapped if our native shell is the
 # same abi as the compiled libsandbox #259244
-sh=$(scanelf -BF'%M#F' /bin/sh)
-sb=$(scanelf -BF'%M#F' "${abs_top_builddir}"/libsandbox/.libs/libsandbox.so)
+sh=$(scanelf -BF'%M %a#F' /bin/sh)
+sb=$(scanelf -BF'%M %a#F' "${abs_top_builddir}"/libsandbox/.libs/libsandbox.so)
 [ "${sh}" = "${sb}" ] && exit 0 || exit 77



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-07-03 19:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-03 19:41 [gentoo-commits] proj/sandbox:master commit in: libsandbox/trace/linux/, /, libsandbox/wrapper-funcs/, libsandbox/, tests/ Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox