diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2012-02-03 01:22:44 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2012-02-03 01:22:44 +0000 |
commit | 8b1524c45f3ff3179ab98bafb866f19e6c632dcf (patch) | |
tree | 8b4ee70f242b22a6bce724a2c27c72e353ba9375 | |
parent | 4f3df078b26899afe0f25d8651b06a5a5b5143e2 (diff) | |
download | strace-ldv/selinux.tar.gz |
Enhance diagnostics when ptrace syscall is disabledldv/selinux
When ptrace(PTRACE_TRACEME, ...) is rejected by kernel with EACCES or
EPERM, it usually means that there is a kernel security policy in effect
that disallowes ptrace syscall. Let's help users by giving them a hint
what is going on and how to deal with it.
* configure.ac: Check for libselinux.
* strace.c (show_security_policy_diagnostics): New function.
(test_ptrace_setoptions_followfork,
test_ptrace_setoptions_for_all): Use it.
-rw-r--r-- | configure.ac | 15 | ||||
-rw-r--r-- | strace.c | 44 |
2 files changed, 53 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac index 789a997dd..c6c43c5fd 100644 --- a/configure.ac +++ b/configure.ac @@ -335,5 +335,20 @@ AC_CACHE_CHECK([for BLKGETSIZE64], [ac_cv_have_blkgetsize64], AC_PATH_PROG([PERL], [perl]) +AC_ARG_WITH([selinux], + AS_HELP_STRING([--without-selinux], + [do not use SELinux library (default: use it if available)]), + [use_selinux=$withval], + [use_selinux=auto]) + +if test "x$use_selinux" != xno; then + AC_CHECK_LIB([selinux], [is_selinux_enabled]) + if test "x$use_selinux" = xyes; then + if test "x$ac_cv_lib_selinux_is_selinux_enabled" != xyes; then + AC_MSG_ERROR([SELinux library was not found or not usable]) + fi + fi +fi + AC_CONFIG_FILES([Makefile tests/Makefile]) AC_OUTPUT @@ -839,6 +839,32 @@ static void kill_save_errno(pid_t pid, int sig) errno = saved_errno; } +#ifdef HAVE_LIBSELINUX +# include <selinux/selinux.h> +#endif + +static void show_security_policy_diagnostics(void) { + if (errno != EACCES && errno != EPERM) + return; + +#ifdef HAVE_LIBSELINUX + if ((is_selinux_enabled() > 0) + && (security_get_boolean_active("deny_ptrace") == 1)) { + fprintf(stderr, + "The SELinux boolean 'deny_ptrace' is enabled, preventing arbitrary processes\n" + "from snooping on each other (as a layered defense against intruders).\n" + "This protection can be disabled by running the following shell command as root:\n" + "\tsetsebool deny_ptrace 0\n" + "See https://fedoraproject.org/wiki/Features/SELinuxDenyPtrace for more information.\n"); + return; + } +#endif + fprintf(stderr, + "A kernel security policy that disallows ptrace syscalls, preventing arbitrary\n" + "processes from snooping on each other as a layered defense against intruders,\n" + "seems to be in effect.\n"); +} + /* * Test whether the kernel support PTRACE_O_TRACECLONE et al options. * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, @@ -857,9 +883,12 @@ test_ptrace_setoptions_followfork(void) perror_msg_and_die("fork"); if (pid == 0) { pid = getpid(); - if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) - perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", - __func__); + if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { + perror_msg("%s: PTRACE_TRACEME doesn't work", + __func__); + show_security_policy_diagnostics(); + die(); + } kill(pid, SIGSTOP); if (fork() < 0) perror_msg_and_die("fork"); @@ -971,10 +1000,13 @@ test_ptrace_setoptions_for_all(void) if (pid == 0) { pid = getpid(); - if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) + if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { + perror_msg("%s: PTRACE_TRACEME doesn't work", + __func__); + show_security_policy_diagnostics(); /* Note: exits with exitcode 1 */ - perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", - __func__); + die(); + } kill(pid, SIGSTOP); _exit(0); /* parent should see entry into this syscall */ } |