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
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 */
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
#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;
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
+#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
+#undef _trace_possible
+#define _trace_possible _trace_possible
+
#ifdef SB_SCHIZO
static const struct syscall_entry syscall_table_32[] = {
#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
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
{
trace_regs *regs = vregs;
if (pers_is_32(regs))
+ /* 32bit x86 */
switch (num) {
case 1: return regs->rbx;
case 2: return regs->rcx;
{
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);
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)
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:
#!/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