@@ -, +, @@ --- configure.ac | 18 +++++++++++++++++- headers.h | 9 +++++++++ libsandbox/Makefile.am | 2 +- libsandbox/libsandbox.c | 39 +++++++++++++++++++++++++++++++++++++++ localdecls.h | 2 ++ 5 files changed, 68 insertions(+), 2 deletions(-) --- a/configure.ac +++ a/configure.ac @@ -74,6 +74,7 @@ AC_CHECK_HEADERS_ONCE([ \ execinfo.h \ fcntl.h \ grp.h \ + kvm.h \ libgen.h \ limits.h \ memory.h \ @@ -101,10 +102,12 @@ AC_CHECK_HEADERS_ONCE([ \ sys/syscall.h \ sys/time.h \ sys/types.h \ + sys/sysctl.h \ sys/user.h \ sys/wait.h \ asm/ptrace.h \ linux/ptrace.h \ + machine/reg.h \ ]) dnl Checks for typedefs, structures, and compiler characteristics. @@ -119,7 +122,7 @@ AC_CHECK_TYPES([sighandler_t, sig_t, __sighandler_t],,,[#include ]) save_CPPFLAGS=$CPPFLAGS CPPFLAGS="-I$srcdir $CPPFLAGS" -AC_CHECK_TYPES([struct user_regs_struct, struct pt_regs],,,[#include "headers.h"]) +AC_CHECK_TYPES([struct user_regs_struct, struct pt_regs, struct reg],,,[#include "headers.h"]) CPPFLAGS=$save_CPPFLAGS dnl Checks for library functions. @@ -180,6 +183,19 @@ AC_CHECK_LIB([sigsegv], [stackoverflow_install_handler], [HAVE_LIBSIGSEGV=false]) AM_CONDITIONAL(HAVE_LIBSIGSEGV, $HAVE_LIBSIGSEGV) +have_libkvm="no" +AC_CHECK_LIB([kvm], [kvm_open], + [have_libkvm="yes"], + [have_libkvm="no"]) +LIBKVM="" +if test "x$have_libkvm" = xyes ; then + AC_DEFINE([HAVE_LIBKVM], [1], [libkvm is available]) + LIBKVM=-lkvm +else + AC_DEFINE([HAVE_LIBKVM], [0], [libkvm is not available]) +fi +AC_SUBST(LIBKVM) + dnl Check for gcc atomic primitives AC_MSG_CHECKING([for __sync_lock_test_and_set]) sltas=no --- a/headers.h +++ a/headers.h @@ -32,6 +32,9 @@ #ifdef HAVE_GRP_H # include #endif +#ifdef HAVE_KVM_H +# include +#endif #ifdef HAVE_LIBGEN_H # include #endif @@ -107,6 +110,9 @@ #ifdef HAVE_SYS_SYSCALL_H # include #endif +#ifdef HAVE_SYS_SYSCTL_H +# include +#endif #ifdef HAVE_SYS_TIME_H # include #endif @@ -119,6 +125,9 @@ #ifdef HAVE_SYS_WAIT_H # include #endif +#ifdef HAVE_MACHINE_REG_H +# include +#endif #ifdef __ia64__ /* what a pos */ # define ia64_fpreg FU_ia64_fpreg --- a/libsandbox/Makefile.am +++ a/libsandbox/Makefile.am @@ -14,7 +14,7 @@ libsandbox_la_CFLAGS = $(CFLAG_EXCEPTIONS) # $(top_builddir)/libsbutil/libsbutil.la libsandbox_la_LIBSBLIB = $(top_builddir)/libsbutil/.libs/libsbutil.a libsandbox_la_LIBADD = \ - -lc $(LIBDL) \ + -lc $(LIBDL) $(LIBKVM) \ $(libsandbox_la_LIBSBLIB) # Do not add -nostdlib or -nostartfiles, as then our constructor # and destructor will not be executed ... --- a/libsandbox/libsandbox.c +++ a/libsandbox/libsandbox.c @@ -124,6 +124,7 @@ static const char *sb_get_fd_dir(void) #endif } +#if !HAVE_LIBKVM static const char *sb_get_cmdline(pid_t pid) { #if !defined(SANDBOX_PROC_1_CMDLINE) && !defined(SANDBOX_PROC_SELF_CMDLINE) && !defined(SANDBOX_PROC_dd_CMDLINE) @@ -135,6 +136,18 @@ static const char *sb_get_cmdline(pid_t pid) sprintf(path, "/proc/%i/cmdline", pid); return path; } +#else /* !HAVE_LIBKVM */ +static char **sb_get_kvm_cmdline(pid_t pid) +{ + int cnt = 0; + char** ret; + kvm_t * kt = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL); + struct kinfo_proc * proc = kvm_getprocs(kt, KERN_PROC_PID | KERN_PROC_ALL, ( pid ? pid : getpid() ), &cnt); + ret = ( cnt > 0 ? kvm_getargv(kt, proc, 0) : NULL); + kvm_close(kt); + return ret; +} +#endif /* !HAVE_LIBKVM */ int canonicalize(const char *path, char *resolved_path) { @@ -358,6 +371,7 @@ char *egetcwd(char *buf, size_t size) return tmpbuf; } +#if !HAVE_LIBKVM static int sb_copy_file_to_fd(const char *file, int ofd) { int ret = -1; @@ -388,6 +402,7 @@ static int sb_copy_file_to_fd(const char *file, int ofd) free(buf); return ret; } +#endif /* !HAVE_LIBKVM */ void sb_dump_backtrace(void) { @@ -397,10 +412,21 @@ void sb_dump_backtrace(void) num_funcs = backtrace(funcs, ARRAY_SIZE(funcs)); backtrace_symbols_fd(funcs, num_funcs, STDERR_FILENO); #endif +#if !HAVE_LIBKVM const char *cmdline = sb_get_cmdline(trace_pid); sb_printf("%s: ", cmdline); sb_copy_file_to_fd(cmdline, STDERR_FILENO); sb_printf("\n\n"); +#else /* !HAVE_LIBKVM */ + char **cmdline = sb_get_kvm_cmdline(trace_pid); + if(cmdline) { + int i; + for(i=0;cmdline[i];i++) sb_printf("%s ", cmdline[i]); + sb_printf("\n\n"); + } + else + sb_printf("libkvm: unable to get cmdline\n\n"); +#endif /* !HAVE_LIBKVM */ } __attribute__((noreturn)) @@ -492,11 +518,24 @@ static bool write_logfile(const char *logfile, const char *func, const char *pat _SB_WRITE_STR(rpath); _SB_WRITE_STR("\nC: "); +#if !HAVE_LIBKVM const char *cmdline = sb_get_cmdline(trace_pid); if (sb_copy_file_to_fd(cmdline, logfd)) { _SB_WRITE_STR("unable to read "); _SB_WRITE_STR(cmdline); } +#else /* !HAVE_LIBKVM */ + char **cmdline = sb_get_kvm_cmdline(trace_pid); + if(cmdline) { + int i; + for(i=0;cmdline[i];i++){ + _SB_WRITE_STR(cmdline[i]); + _SB_WRITE_STR(" "); + } + } + else + _SB_WRITE_STR("unable to get cmdline from libkvm"); +#endif /* !HAVE_LIBKVM */ _SB_WRITE_STR("\n"); return true; --- a/localdecls.h +++ a/localdecls.h @@ -67,6 +67,8 @@ typedef __sighandler_t sighandler_t; typedef struct pt_regs trace_regs; #elif defined(HAVE_STRUCT_USER_REGS_STRUCT) typedef struct user_regs_struct trace_regs; +#elif defined(HAVE_STRUCT_REG) +typedef struct reg trace_regs; #else # error "unable to find struct for tracing regs" #endif --