aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2016-09-29 16:32:33 +0200
committerKarel Zak <kzak@redhat.com>2016-09-29 16:32:33 +0200
commit8e4925016875c6a4f2ab4f833ba66f0fc57396a2 (patch)
treea6cb7d8cd2d619895c6de6975fe6c904875e5cc5
parenta0a8e9884443601abf9f06b715f2f6bb0820cbad (diff)
downloadutil-linux-8e4925016875c6a4f2ab4f833ba66f0fc57396a2.tar.gz
su,runuser: add libseccomp based workaround for TIOCSTI ioctl
This patch add libseccomp based syscalls filter to disable TIOCSTI ioctl in su/runuser children. IMHO it is not elegant solution due to dependence on libseccomp (--without-seccomp if hate it)... but there is nothing better for now. Addresses: CVE-2016-2779 Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--configure.ac16
-rw-r--r--login-utils/Makemodule.am7
-rw-r--r--login-utils/su-common.c20
3 files changed, 40 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 680f5b6878..6346865138 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1691,6 +1691,22 @@ AS_IF([test "x$with_user" != xno], [
])
AM_CONDITIONAL([HAVE_USER], [test "x$have_user" = xyes])
+
+AC_ARG_WITH([libseccomp], AS_HELP_STRING([--without-seccomp], [compile without libseccomp]),
+ [], [with_seccomp=check]
+)
+have_seccomp=no
+AS_IF([test "x$with_seccomp" != xno], [
+ PKG_CHECK_MODULES(SECCOMP,[libseccomp], [have_seccomp=yes], [have_seccomp=no])
+ AS_CASE([$with_seccomp:$have_seccomp],
+ [yes:no],
+ [AC_MSG_ERROR([seccomp selected but libseccomp not found])],
+ [*:yes],
+ [AC_DEFINE([HAVE_LIBSECCOMP], [1], [Define if libseccomp is available])]
+ )
+])
+
+
AC_ARG_ENABLE([chfn-chsh-password],
AS_HELP_STRING([--disable-chfn-chsh-password], [do not require the user to enter the password in chfn and chsh]),
[], [enable_chfn_chsh_password=yes]
diff --git a/login-utils/Makemodule.am b/login-utils/Makemodule.am
index be07ace43f..12f27e12e4 100644
--- a/login-utils/Makemodule.am
+++ b/login-utils/Makemodule.am
@@ -140,9 +140,9 @@ su_SOURCES = \
login-utils/su-common.h \
login-utils/logindefs.c \
login-utils/logindefs.h
-su_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS)
+su_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS) $(SECCOMP_CFLAGS)
su_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
-su_LDADD = $(LDADD) libcommon.la -lpam
+su_LDADD = $(LDADD) libcommon.la -lpam $(SECCOMP_LIBS)
if HAVE_LINUXPAM
su_LDADD += -lpam_misc
endif
@@ -158,7 +158,8 @@ runuser_SOURCES = \
login-utils/su-common.h \
login-utils/logindefs.c \
login-utils/logindefs.h
-runuser_LDADD = $(LDADD) libcommon.la -lpam
+runuser_LDADD = $(LDADD) libcommon.la -lpam $(SECCOMP_LIBS)
+runuser_CFLAGS = $(AM_CFLAGS) $(SECCOMP_CFLAGS)
if HAVE_LINUXPAM
runuser_LDADD += -lpam_misc
endif
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
index ff20a2f478..5ab2a1ac03 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -59,6 +59,9 @@ enum
#include <sys/wait.h>
#include <syslog.h>
#include <utmp.h>
+#ifdef HAVE_LIBSECCOMP
+# include <seccomp.h>
+#endif
#include "err.h"
@@ -674,6 +677,21 @@ restricted_shell (const char *shell)
return true;
}
+static void disable_tty_hijack(void)
+{
+#ifdef HAVE_LIBSECCOMP
+ scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
+ if (!ctx)
+ err(EXIT_FAILURE, _("failed to initialize seccomp context"));
+ if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ioctl), 1,
+ SCMP_A1(SCMP_CMP_EQ, (int)TIOCSTI)) < 0)
+ err(EXIT_FAILURE, _("failed to add seccomp rule"));
+ if (seccomp_load(ctx) < 0)
+ err(EXIT_FAILURE, _("failed to load seccomp rule"));
+ seccomp_release(ctx);
+#endif /* HAVE_LIBSECCOMP */
+}
+
static void __attribute__((__noreturn__))
usage (int status)
{
@@ -970,6 +988,8 @@ su_main (int argc, char **argv, int mode)
change_identity (pw);
if (!same_session)
setsid ();
+ else
+ disable_tty_hijack();
/* Set environment after pam_open_session, which may put KRB5CCNAME
into the pam_env, etc. */