summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2017-10-19 20:28:57 +0100
committerSam Thursfield <sam.thursfield@codethink.co.uk>2017-10-19 21:29:11 +0100
commit9e74a6dc5a2bdca647b3ccc129af41fb1a543483 (patch)
treea416fdd13fe845d6d0790c4828faf0ba38353324
parentfe1b7da17caa0f0e9909aed56061ab9c9f803a4d (diff)
downloadtracker-wip/sam/meson-subproject.tar.gz
libtracker-common: Add tracker-seccomp from the libtracker-miners librarywip/sam/meson-subproject
This module is only used in the tracker-miners repo. However, when building this repo as a Meson subproject of tracker-miners.git, we can only build one version of libtracker-common so we need to have it present in our version.
-rw-r--r--config.h.meson.in3
-rw-r--r--meson.build2
-rw-r--r--src/libtracker-common/meson.build8
-rw-r--r--src/libtracker-common/tracker-seccomp.c228
-rw-r--r--src/libtracker-common/tracker-seccomp.h35
5 files changed, 275 insertions, 1 deletions
diff --git a/config.h.meson.in b/config.h.meson.in
index 25d292062..e3cab84ca 100644
--- a/config.h.meson.in
+++ b/config.h.meson.in
@@ -69,6 +69,9 @@
/* Define if we have libiptcdata */
#mesondefine HAVE_LIBIPTCDATA
+/* Define if we have libseccomp */
+#mesondefine HAVE_LIBSECCOMP
+#
/* Define if we have libstemmer */
#mesondefine HAVE_LIBSTEMMER
diff --git a/meson.build b/meson.build
index 976fa154f..86e150ba8 100644
--- a/meson.build
+++ b/meson.build
@@ -26,6 +26,7 @@ gobject_introspection = dependency('gobject-introspection-1.0')
icu_i18n = dependency('icu-i18n', version: '> 4.8.1.1', required: false)
icu_uc = dependency('icu-uc', version: '> 4.8.1.1', required: false)
json_glib = dependency('json-glib-1.0', version: '>= 1.0', required: true)
+libseccomp = dependency('libseccomp', version: '>= 2.0', required: false)
libsoup = dependency('libsoup-2.4', version: '> 2.40', required: true)
libxml2 = dependency('libxml-2.0', version: '> 2.6')
network_manager = dependency('libnm', required: false)
@@ -230,6 +231,7 @@ conf.set('HAVE_BUILTIN_FTS', sqlite3_has_builtin_fts5)
conf.set('HAVE_ENCA', charset_library_name == 'enca')
conf.set10('HAVE_LIBICU', unicode_library_name == 'icu')
conf.set('HAVE_LIBICU_CHARSET_DETECTION', charset_library_name == 'icu')
+conf.set('HAVE_LIBSECCOMP', libseccomp.found())
conf.set('HAVE_LIBSTEMMER', have_libstemmer)
conf.set('HAVE_LIBUNISTRING', unicode_library_name == 'unistring')
conf.set('HAVE_NETWORK_MANAGER', network_manager.found())
diff --git a/src/libtracker-common/meson.build b/src/libtracker-common/meson.build
index c9a1defb9..9f5106650 100644
--- a/src/libtracker-common/meson.build
+++ b/src/libtracker-common/meson.build
@@ -26,6 +26,7 @@ tracker_common_sources = [
'tracker-locale.c',
'tracker-parser-utils.c',
'tracker-language.c',
+ 'tracker-seccomp.c',
enums[0], enums[1],
tracker_common_parser_sha1_header,
]
@@ -39,9 +40,14 @@ endif
# FIXME: need to link against -lkvm on OpenBSD, see configure.ac
tracker_common_dependencies = [glib, gio, gio_unix, libmath]
+tracker_common_private_dependencies = [unicode_library]
+if libseccomp.found()
+ tracker_common_private_dependencies += [libseccomp]
+endif
+
libtracker_common = library('tracker-common',
tracker_common_sources,
- dependencies: tracker_common_dependencies + [unicode_library],
+ dependencies: tracker_common_dependencies + tracker_common_private_dependencies,
c_args: tracker_c_args,
include_directories: [configinc, srcinc],
install: true,
diff --git a/src/libtracker-common/tracker-seccomp.c b/src/libtracker-common/tracker-seccomp.c
new file mode 100644
index 000000000..ec873f5e0
--- /dev/null
+++ b/src/libtracker-common/tracker-seccomp.c
@@ -0,0 +1,228 @@
+/*
+ * 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 { \
+ int allow_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
+ if (allow_rule_syscall_number == __NR_SCMP_ERROR || \
+ seccomp_rule_add (ctx, SCMP_ACT_ALLOW, allow_rule_syscall_number, 0) < 0) \
+ goto out; \
+} G_STMT_END
+
+#define ERROR_RULE(call, error) G_STMT_START { \
+ int error_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
+ if (error_rule_syscall_number == __NR_SCMP_ERROR || \
+ seccomp_rule_add (ctx, SCMP_ACT_ERRNO (error), error_rule_syscall_number, 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 (mmap2);
+ ALLOW_RULE (munmap);
+ ALLOW_RULE (mremap);
+ ALLOW_RULE (mprotect);
+ ALLOW_RULE (madvise);
+ ERROR_RULE (mlock, EPERM);
+ ERROR_RULE (mlock2, EPERM);
+ ERROR_RULE (munlock, EPERM);
+ ERROR_RULE (mlockall, EPERM);
+ ERROR_RULE (munlockall, EPERM);
+ /* Process management */
+ ALLOW_RULE (exit_group);
+ ALLOW_RULE (getuid);
+ ALLOW_RULE (getuid32);
+ ALLOW_RULE (geteuid);
+ ALLOW_RULE (geteuid32);
+ ALLOW_RULE (getppid);
+ ALLOW_RULE (gettid);
+ ALLOW_RULE (getpid);
+ ALLOW_RULE (exit);
+ ALLOW_RULE (getrusage);
+ ALLOW_RULE (getrlimit);
+ /* Basic filesystem access */
+ ALLOW_RULE (fstat);
+ ALLOW_RULE (fstat64);
+ ALLOW_RULE (stat);
+ ALLOW_RULE (stat64);
+ ALLOW_RULE (statfs);
+ ALLOW_RULE (statfs64);
+ ALLOW_RULE (lstat);
+ ALLOW_RULE (lstat64);
+ ALLOW_RULE (access);
+ ALLOW_RULE (getdents);
+ ALLOW_RULE (getdents64);
+ ALLOW_RULE (readlink);
+ ALLOW_RULE (readlinkat);
+ ALLOW_RULE (utime);
+ ALLOW_RULE (time);
+ ALLOW_RULE (fsync);
+ ALLOW_RULE (umask);
+ /* 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);
+ ALLOW_RULE (waitid);
+ ALLOW_RULE (waitpid);
+ ALLOW_RULE (wait4);
+ /* Main loops */
+ ALLOW_RULE (poll);
+ ALLOW_RULE (ppoll);
+ ALLOW_RULE (fcntl);
+ ALLOW_RULE (fcntl64);
+ ALLOW_RULE (eventfd);
+ ALLOW_RULE (eventfd2);
+ ALLOW_RULE (pipe);
+ ALLOW_RULE (pipe2);
+ /* System */
+ ALLOW_RULE (uname);
+ ALLOW_RULE (sysinfo);
+ ALLOW_RULE (prctl);
+ ALLOW_RULE (getrandom);
+ ALLOW_RULE (clock_gettime);
+ ALLOW_RULE (clock_getres);
+ ALLOW_RULE (gettimeofday);
+ /* Descriptors */
+ ALLOW_RULE (close);
+ ALLOW_RULE (read);
+ ALLOW_RULE (pread64);
+ ALLOW_RULE (lseek);
+ ALLOW_RULE (_llseek);
+ ALLOW_RULE (fadvise64);
+ ALLOW_RULE (write);
+ ALLOW_RULE (writev);
+ ALLOW_RULE (dup);
+ ALLOW_RULE (dup2);
+ ALLOW_RULE (dup3);
+ /* 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/openat, 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;
+
+ if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 1,
+ SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) < 0)
+ goto out;
+ if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(openat), 1,
+ SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) < 0)
+ goto out;
+ if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(openat), 1,
+ SCMP_CMP(2, 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 000000000..0e0333024
--- /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__ */