[tracker/tracker-1.8] libtracker-common: Implement sandboxing through libseccomp



commit e1761a93d3d5483a511cb702717d7ef67577c54e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Dec 6 17:03:17 2016 +0100

    libtracker-common: Implement sandboxing through libseccomp
    
    The threads calling the new tracker_seccomp_init() function, and all
    threads/processes spawned from these, will enter a restricted mode
    where only a few sensible syscalls are allowed, and more specifically,
    filesystem/socket access are restricted to being respectively
    readonly and local only.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=764786

 configure.ac                            |   20 ++++
 src/libtracker-common/Makefile.am       |    2 +
 src/libtracker-common/tracker-common.h  |    1 +
 src/libtracker-common/tracker-seccomp.c |  176 +++++++++++++++++++++++++++++++
 src/libtracker-common/tracker-seccomp.h |   35 ++++++
 5 files changed, 234 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 6bd6d93..eddc690 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2626,6 +2626,20 @@ fi
 
 AM_CONDITIONAL(HAVE_ARTWORK, test "x$have_artwork" = "xyes")
 
+##################################################################
+# Check for libseccomp
+##################################################################
+
+PKG_CHECK_MODULES(LIBSECCOMP,
+                  [libseccomp >= 2.0],
+                  [have_libseccomp=yes],
+                  [have_libseccomp=no])
+
+if test "$have_libseccomp" = "yes"; then
+   LIBTRACKER_COMMON_LIBS="$LIBTRACKER_COMMON_LIBS $LIBSECCOMP_LIBS"
+   LIBTRACKER_COMMON_CFLAGS="$LIBTRACKER_COMMON_CFLAGS $LIBSECCOMP_CFLAGS"
+   AC_DEFINE(HAVE_LIBSECCOMP, [], [Define if we have libseccomp])
+fi
 
 ##################################################################
 # Write generated files
@@ -2892,3 +2906,9 @@ WARNING:
 
 "
 fi
+
+if test "$have_libseccomp" = "no"; then
+echo "
+WARNING: libseccomp was not found, build will not be prevented, but this is a security flaw.
+"
+fi
diff --git a/src/libtracker-common/Makefile.am b/src/libtracker-common/Makefile.am
index 348b136..8ba070a 100644
--- a/src/libtracker-common/Makefile.am
+++ b/src/libtracker-common/Makefile.am
@@ -27,6 +27,7 @@ libtracker_common_la_SOURCES = \
        tracker-ioprio.c \
        tracker-log.c \
        tracker-sched.c \
+       tracker-seccomp.c \
        tracker-type-utils.c \
        tracker-utils.c \
        tracker-locale.c \
@@ -42,6 +43,7 @@ noinst_HEADERS = \
        tracker-date-time.h \
        tracker-file-utils.h \
        tracker-sched.h \
+       tracker-seccomp.h \
        tracker-type-utils.h \
        tracker-utils.h \
        tracker-locale.h \
diff --git a/src/libtracker-common/tracker-common.h b/src/libtracker-common/tracker-common.h
index 1af7393..2434b7f 100644
--- a/src/libtracker-common/tracker-common.h
+++ b/src/libtracker-common/tracker-common.h
@@ -36,6 +36,7 @@
 #include "tracker-log.h"
 #include "tracker-parser.h"
 #include "tracker-sched.h"
+#include "tracker-seccomp.h"
 #include "tracker-type-utils.h"
 #include "tracker-utils.h"
 #include "tracker-locale.h"
diff --git a/src/libtracker-common/tracker-seccomp.c b/src/libtracker-common/tracker-seccomp.c
new file mode 100644
index 0000000..3c3f449
--- /dev/null
+++ b/src/libtracker-common/tracker-seccomp.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2016, Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "tracker-seccomp.h"
+
+#ifdef HAVE_LIBSECCOMP
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+
+#include <seccomp.h>
+
+#define ALLOW_RULE(call) G_STMT_START { if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(call), 0) < 0) 
goto out; } G_STMT_END
+
+gboolean
+tracker_seccomp_init (void)
+{
+       scmp_filter_ctx ctx;
+
+       ctx = seccomp_init (SCMP_ACT_TRAP);
+       if (ctx == NULL)
+               return FALSE;
+
+       /* Memory management */
+       ALLOW_RULE (brk);
+       ALLOW_RULE (mmap);
+       ALLOW_RULE (munmap);
+       ALLOW_RULE (mremap);
+       ALLOW_RULE (mprotect);
+       ALLOW_RULE (madvise);
+       /* Process management */
+       ALLOW_RULE (exit_group);
+       ALLOW_RULE (getuid);
+       ALLOW_RULE (geteuid);
+       ALLOW_RULE (getppid);
+       ALLOW_RULE (gettid);
+       ALLOW_RULE (exit);
+       /* Basic filesystem access */
+       ALLOW_RULE (fstat);
+       ALLOW_RULE (stat);
+       ALLOW_RULE (statfs);
+       ALLOW_RULE (lstat);
+       ALLOW_RULE (access);
+       ALLOW_RULE (getdents);
+       ALLOW_RULE (readlink);
+       ALLOW_RULE (readlinkat);
+       ALLOW_RULE (utime);
+       ALLOW_RULE (fsync);
+       /* Processes and threads */
+       ALLOW_RULE (clone);
+       ALLOW_RULE (futex);
+       ALLOW_RULE (set_robust_list);
+       ALLOW_RULE (rt_sigaction);
+       ALLOW_RULE (rt_sigprocmask);
+       ALLOW_RULE (sched_yield);
+       ALLOW_RULE (sched_getaffinity);
+       ALLOW_RULE (nanosleep);
+       /* Main loops */
+       ALLOW_RULE (poll);
+       ALLOW_RULE (ppoll);
+       ALLOW_RULE (fcntl);
+       ALLOW_RULE (eventfd2);
+       ALLOW_RULE (pipe);
+       ALLOW_RULE (pipe2);
+       /* System */
+       ALLOW_RULE (uname);
+       ALLOW_RULE (sysinfo);
+       ALLOW_RULE (prctl);
+       ALLOW_RULE (getrandom);
+       /* Descriptors */
+       ALLOW_RULE (close);
+       ALLOW_RULE (read);
+       ALLOW_RULE (pread64);
+       ALLOW_RULE (lseek);
+       ALLOW_RULE (fadvise64);
+       ALLOW_RULE (write);
+       ALLOW_RULE (writev);
+       /* Needed by some GStreamer modules doing crazy stuff, less
+        * scary thanks to the restriction below about sockets being
+        * local.
+        */
+       ALLOW_RULE (connect);
+       ALLOW_RULE (send);
+       ALLOW_RULE (sendto);
+       ALLOW_RULE (sendmsg);
+       ALLOW_RULE (recv);
+       ALLOW_RULE (recvmsg);
+       ALLOW_RULE (recvfrom);
+       ALLOW_RULE (getsockname);
+       ALLOW_RULE (getpeername);
+       ALLOW_RULE (shutdown);
+
+       /* Special requirements for socket/socketpair, only on AF_UNIX/AF_LOCAL */
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
+                             SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) < 0)
+               goto out;
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
+                             SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) < 0)
+               goto out;
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 1,
+                             SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) < 0)
+               goto out;
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 1,
+                             SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) < 0)
+               goto out;
+
+       /* Special requirements for ioctl, allowed on stdout/stderr */
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1,
+                             SCMP_CMP(0, SCMP_CMP_EQ, 1)) < 0)
+               goto out;
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1,
+                             SCMP_CMP(0, SCMP_CMP_EQ, 2)) < 0)
+               goto out;
+
+       /* Special requirements for open, allow O_RDONLY calls, but fail
+        * if write permissions are requested.
+        */
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
+                             SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) < 0)
+               goto out;
+       if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(open), 1,
+                             SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) < 0)
+               goto out;
+       if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(open), 1,
+                             SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) < 0)
+               goto out;
+
+       g_debug ("Loading seccomp rules.");
+
+       if (seccomp_load (ctx) >= 0)
+               return TRUE;
+
+out:
+       g_critical ("Failed to load seccomp rules.");
+       seccomp_release (ctx);
+       return FALSE;
+}
+
+#else /* HAVE_LIBSECCOMP */
+
+gboolean
+tracker_seccomp_init (void)
+{
+       g_warning ("No seccomp support compiled-in.");
+       return TRUE;
+}
+
+#endif /* HAVE_LIBSECCOMP */
diff --git a/src/libtracker-common/tracker-seccomp.h b/src/libtracker-common/tracker-seccomp.h
new file mode 100644
index 0000000..0e03330
--- /dev/null
+++ b/src/libtracker-common/tracker-seccomp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016, Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKER_SECCOMP_H__
+#define __TRACKER_SECCOMP_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#if !defined (__LIBTRACKER_COMMON_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-common/tracker-common.h> must be included directly."
+#endif
+
+gboolean tracker_seccomp_init (void);
+
+G_END_DECLS
+
+#endif /* __TRACKER_SECCOMP_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]