diff --git a/CMakeLists.txt b/CMakeLists.txt
index 83c5223199237e578df95ea8420ded18b04ddba5..eb92f80a6d3d3ab801856446e3b345f05ee52f2e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ endif(COMMAND cmake_policy)
 project (pkcs11 C)
 
 set(PKCS11_PROXY_SRCS gck-rpc-module.c gck-rpc-message.c gck-rpc-util.c egg-buffer.c)
-set(PKCS11_DAEMON_SRCS egg-buffer.c gck-rpc-daemon-standalone.c gck-rpc-dispatch.c gck-rpc-message.c gck-rpc-util.c)
+set(PKCS11_DAEMON_SRCS egg-buffer.c gck-rpc-daemon-standalone.c gck-rpc-dispatch.c gck-rpc-message.c gck-rpc-util.c syscall-reporter.c syscall-names.h)
 
 add_definitions(-Wall)
 add_library(pkcs11-proxy SHARED ${PKCS11_PROXY_SRCS})
@@ -38,3 +38,8 @@ target_link_libraries (pkcs11-daemon dl pthread)
 
 install_targets (/lib pkcs11-proxy)
 install_targets (/bin pkcs11-daemon)
+
+add_custom_command(
+   OUTPUT syscall-names.h 
+   COMMAND ${CMAKE_SOURCE_DIR}/mksyscalls.sh
+   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
diff --git a/gck-rpc-daemon-standalone.c b/gck-rpc-daemon-standalone.c
index a0039f2f944644f7be3a0d9ce65fb27f1da4d1fc..3f17e1eb62e7b9f6382360634dbdb0cf3ac70bb2 100644
--- a/gck-rpc-daemon-standalone.c
+++ b/gck-rpc-daemon-standalone.c
@@ -42,6 +42,63 @@
 
 #define SOCKET_PATH "tcp://127.0.0.1"
 
+#include "seccomp-bpf.h"
+#include "syscall-reporter.h"
+
+static int install_syscall_filter(void)
+{
+	struct sock_filter filter[] = {
+	        /* Validate architecture. */
+		VALIDATE_ARCHITECTURE,
+		/* Grab the system call number. */
+		EXAMINE_SYSCALL,
+		/* List allowed syscalls. */
+		ALLOW_SYSCALL(rt_sigreturn),
+#ifdef __NR_sigreturn
+		ALLOW_SYSCALL(sigreturn),
+#endif
+		ALLOW_SYSCALL(exit_group),
+		ALLOW_SYSCALL(exit),
+		ALLOW_SYSCALL(read),
+		ALLOW_SYSCALL(write),
+                ALLOW_SYSCALL(futex),
+                ALLOW_SYSCALL(brk),
+                ALLOW_SYSCALL(open),
+                ALLOW_SYSCALL(fstat64),
+                ALLOW_SYSCALL(mmap2),
+                ALLOW_SYSCALL(mprotect),
+                ALLOW_SYSCALL(close),
+                ALLOW_SYSCALL(access),
+                ALLOW_SYSCALL(munmap),
+                ALLOW_SYSCALL(time),
+                ALLOW_SYSCALL(_llseek),
+                ALLOW_SYSCALL(stat64),
+                ALLOW_SYSCALL(fcntl64),
+                ALLOW_SYSCALL(mlock),
+                ALLOW_SYSCALL(munlock),
+		KILL_PROCESS,
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		perror("prctl(NO_NEW_PRIVS)");
+		goto failed;
+	}
+	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+		perror("prctl(SECCOMP)");
+		goto failed;
+	}
+	return 0;
+
+failed:
+	if (errno == EINVAL)
+		fprintf(stderr, "SECCOMP_FILTER is not available. :(\n");
+	return 1;
+}
+
 #if 0
 /* Sample configuration for loading NSS remotely */
 static CK_C_INITIALIZE_ARGS p11_init_args = {
@@ -72,6 +129,12 @@ int main(int argc, char *argv[])
 	int sock, ret;
 	CK_RV rv;
 
+
+        if (install_syscall_reporter())
+                return 1;
+        if (install_syscall_filter())
+        	return 1;
+
 	/* The module to load is the argument */
 	if (argc != 2 && argc != 3)
 		usage();
diff --git a/mksyscalls.sh b/mksyscalls.sh
new file mode 100755
index 0000000000000000000000000000000000000000..47b4a96d5b0756a32fcd3d9e9e6bbebf4683b74d
--- /dev/null
+++ b/mksyscalls.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+(echo "static const char *syscall_names[] = {"
+echo "#include <sys/syscall.h>" | cpp -dM | grep '^#define __NR_' | LC_ALL=C sed -r -n -e 's/^\#define[ \t]+__NR_([a-z0-9_]+)[ \t]+([0-9]+)(.*)/ [\2] = "\1",/p'
+echo "};")> syscall-names.h
diff --git a/seccomp-bpf.h b/seccomp-bpf.h
new file mode 100644
index 0000000000000000000000000000000000000000..b123787ebd1c0dadd07e7c2568aa689b8476b32f
--- /dev/null
+++ b/seccomp-bpf.h
@@ -0,0 +1,81 @@
+/*
+ * seccomp example for x86 (32-bit and 64-bit) with BPF macros
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Authors:
+ *  Will Drewry <wad@chromium.org>
+ *  Kees Cook <keescook@chromium.org>
+ *
+ * The code may be used by anyone for any purpose, and can serve as a
+ * starting point for developing applications using mode 2 seccomp.
+ */
+#ifndef _SECCOMP_BPF_H_
+#define _SECCOMP_BPF_H_
+
+#define _GNU_SOURCE 1
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/prctl.h>
+#ifndef PR_SET_NO_NEW_PRIVS
+# define PR_SET_NO_NEW_PRIVS 38
+#endif
+
+#include <linux/unistd.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#ifdef HAVE_LINUX_SECCOMP_H
+# include <linux/seccomp.h>
+#endif
+#ifndef SECCOMP_MODE_FILTER
+# define SECCOMP_MODE_FILTER	2 /* uses user-supplied filter. */
+# define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+# define SECCOMP_RET_TRAP	0x00030000U /* disallow and force a SIGSYS */
+# define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
+struct seccomp_data {
+    int nr;
+    __u32 arch;
+    __u64 instruction_pointer;
+    __u64 args[6];
+};
+#endif
+#ifndef SYS_SECCOMP
+# define SYS_SECCOMP 1
+#endif
+
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+#define arch_nr (offsetof(struct seccomp_data, arch))
+
+#if defined(__i386__)
+# define REG_SYSCALL	REG_EAX
+# define ARCH_NR	AUDIT_ARCH_I386
+#elif defined(__x86_64__)
+# define REG_SYSCALL	REG_RAX
+# define ARCH_NR	AUDIT_ARCH_X86_64
+#else
+# warning "Platform does not support seccomp filter yet"
+# define REG_SYSCALL	0
+# define ARCH_NR	0
+#endif
+
+#define VALIDATE_ARCHITECTURE \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \
+	BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
+
+#define EXAMINE_SYSCALL \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr)
+
+#define ALLOW_SYSCALL(name) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1), \
+	BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
+
+#define KILL_PROCESS \
+	BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
+
+#endif /* _SECCOMP_BPF_H_ */
diff --git a/syscall-reporter.c b/syscall-reporter.c
new file mode 100644
index 0000000000000000000000000000000000000000..ec3b254e25e0f959aa0523493ee1f7783f3d49a5
--- /dev/null
+++ b/syscall-reporter.c
@@ -0,0 +1,76 @@
+/*
+ * syscall reporting example for seccomp
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Authors:
+ *  Will Drewry <wad@chromium.org>
+ *  Kees Cook <keescook@chromium.org>
+ *
+ * The code may be used by anyone for any purpose, and can serve as a
+ * starting point for developing applications using mode 2 seccomp.
+ */
+#include "syscall-reporter.h"
+#include "syscall-names.h"
+
+const char * const msg_needed = "Looks like you also need syscall: ";
+
+/* Since "sprintf" is technically not signal-safe, reimplement %d here. */
+static void write_uint(char *buf, unsigned int val)
+{
+	int width = 0;
+	unsigned int tens;
+
+	if (val == 0) {
+		strcpy(buf, "0");
+		return;
+	}
+	for (tens = val; tens; tens /= 10)
+		++ width;
+	buf[width] = '\0';
+	for (tens = val; tens; tens /= 10)
+		buf[--width] = '0' + (tens % 10);
+}
+
+static void reporter(int nr, siginfo_t *info, void *void_context)
+{
+	char buf[128];
+	ucontext_t *ctx = (ucontext_t *)(void_context);
+	unsigned int syscall;
+	if (info->si_code != SYS_SECCOMP)
+		return;
+	if (!ctx)
+		return;
+	syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
+	strcpy(buf, msg_needed);
+	if (syscall < sizeof(syscall_names)) {
+		strcat(buf, syscall_names[syscall]);
+		strcat(buf, "(");
+	}
+	write_uint(buf + strlen(buf), syscall);
+	if (syscall < sizeof(syscall_names))
+		strcat(buf, ")");
+	strcat(buf, "\n");
+	write(STDERR_FILENO, buf, strlen(buf));
+	_exit(1);
+}
+
+int install_syscall_reporter(void)
+{
+	struct sigaction act;
+	sigset_t mask;
+	memset(&act, 0, sizeof(act));
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGSYS);
+
+	act.sa_sigaction = &reporter;
+	act.sa_flags = SA_SIGINFO;
+	if (sigaction(SIGSYS, &act, NULL) < 0) {
+		perror("sigaction");
+		return -1;
+	}
+	if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
+		perror("sigprocmask");
+		return -1;
+	}
+	return 0;
+}
diff --git a/syscall-reporter.h b/syscall-reporter.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea4847e458d16379ea216264ee7e54661cb907f1
--- /dev/null
+++ b/syscall-reporter.h
@@ -0,0 +1,28 @@
+/*
+ * syscall reporting example for seccomp
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Authors:
+ *  Kees Cook <keescook@chromium.org>
+ *  Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose, and can serve as a
+ * starting point for developing applications using mode 2 seccomp.
+ */
+#ifndef _BPF_REPORTER_H_
+#define _BPF_REPORTER_H_
+
+#include "seccomp-bpf.h"
+
+/* Since this redfines "KILL_PROCESS" into a TRAP for the reporter hook,
+ * we want to make sure it stands out in the build as it should not be
+ * used in the final program.
+ */
+#warning "You've included the syscall reporter. Do not use in production!"
+#undef KILL_PROCESS
+#define KILL_PROCESS \
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP)
+
+extern int install_syscall_reporter(void);
+
+#endif