]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
su,runuser: add libseccomp based workaround for TIOCSTI ioctl
authorKarel Zak <kzak@redhat.com>
Thu, 29 Sep 2016 14:32:33 +0000 (16:32 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 29 Sep 2016 14:32:33 +0000 (16:32 +0200)
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>
configure.ac
login-utils/Makemodule.am
login-utils/su-common.c

index 680f5b687859bb60946cb50d5efd5373d4515d77..6346865138c7ee32c518f62ed40a0982446dc594 100644 (file)
@@ -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]
index be07ace43f4fa4d0aff4bc75862c4a45cf271c61..12f27e12e45e7822063ccb745b3404774db09846 100644 (file)
@@ -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
index ff20a2f47878772a8b44fd88ef02440c1c3bb5ce..5ab2a1ac037b5e405873f595f5e0d6a4056302cf 100644 (file)
@@ -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.  */