[tracker-miners/wip/carlosg/better-extractor-errors: 5/5] libtracker-miners-common: Add SIGSYS handler for seccomp




commit 03e6721c90ea9e947b73f2b3e70d5c5ecd206a57
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Nov 11 11:04:37 2020 +0100

    libtracker-miners-common: Add SIGSYS handler for seccomp
    
    We can handle SIGSYS, and provide a more descriptive error about
    the syscall that got trapped. Unfortunately, there's some obstacles
    to having this error message end up in "tracker3 status":
    
    - This is a signal handler, and it's unsafe to do a fair amount of
      stuff.
    - The handler runs on the sandboxed thread, so opening and writing
      the report file is out of the question
    - Even if we could write it, we still have an unclean exit, restart
      tracker-extract-3, and handle the "crashed" file. So the error
      would be overwritten by a less useful "Crash/hang in file".
    
    Content ourselves to printerr, that'll at least be caught in logs,
    shown with "tracker3 extract <file>", etc.

 src/libtracker-miners-common/tracker-seccomp.c | 39 ++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
---
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index 01887e829..4b85c8734 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -38,6 +38,10 @@
 
 #include <seccomp.h>
 
+#ifndef SYS_SECCOMP
+#define SYS_SECCOMP 1
+#endif
+
 #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 || \
@@ -52,11 +56,46 @@
                goto out; \
 } G_STMT_END
 
+static void
+sigsys_handler (gint       signal,
+                siginfo_t *info,
+                gpointer   context)
+{
+       if (info->si_signo == SIGSYS &&
+           info->si_code == SYS_SECCOMP) {
+               char *syscall_name;
+
+               syscall_name = seccomp_syscall_resolve_num_arch (SCMP_ARCH_NATIVE,
+                                                                info->si_syscall);
+               g_printerr ("Disallowed syscall \"%s\" caught in sandbox\n", syscall_name);
+               free (syscall_name);
+       }
+}
+
+static gboolean
+initialize_sigsys_handler (void)
+{
+       struct sigaction act = { 0 };
+
+       sigemptyset (&act.sa_mask);
+       sigaddset (&act.sa_mask, SIGSYS);
+       act.sa_flags = SA_SIGINFO;
+       act.sa_sigaction = sigsys_handler;
+
+       if (sigaction (SIGSYS, &act, NULL) < 0)
+               return FALSE;
+
+       return TRUE;
+}
+
 gboolean
 tracker_seccomp_init (void)
 {
        scmp_filter_ctx ctx;
 
+       if (!initialize_sigsys_handler ())
+               return FALSE;
+
        ctx = seccomp_init (SCMP_ACT_TRAP);
        if (ctx == NULL)
                return FALSE;


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