22c213
From 6f5cf644bebc189bdb16f1caf3d7c47835d7c287 Mon Sep 17 00:00:00 2001
22c213
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
22c213
Date: Mon, 27 Jan 2020 19:01:36 +0100
22c213
Subject: [PATCH 065/116] virtiofsd: add --syslog command-line option
22c213
MIME-Version: 1.0
22c213
Content-Type: text/plain; charset=UTF-8
22c213
Content-Transfer-Encoding: 8bit
22c213
22c213
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
22c213
Message-id: <20200127190227.40942-62-dgilbert@redhat.com>
22c213
Patchwork-id: 93509
22c213
O-Subject: [RHEL-AV-8.2 qemu-kvm PATCH 061/112] virtiofsd: add --syslog command-line option
22c213
Bugzilla: 1694164
22c213
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
22c213
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
22c213
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
22c213
22c213
From: Stefan Hajnoczi <stefanha@redhat.com>
22c213
22c213
Sometimes collecting output from stderr is inconvenient or does not fit
22c213
within the overall logging architecture.  Add syslog(3) support for
22c213
cases where stderr cannot be used.
22c213
22c213
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
22c213
dgilbert: Reworked as a logging function
22c213
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
22c213
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
22c213
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
22c213
(cherry picked from commit f185621d41f03a23b55795b89e6584253fa23505)
22c213
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
22c213
---
22c213
 tools/virtiofsd/fuse_lowlevel.h  |  1 +
22c213
 tools/virtiofsd/helper.c         |  2 ++
22c213
 tools/virtiofsd/passthrough_ll.c | 50 +++++++++++++++++++++++++++++++++++++---
22c213
 tools/virtiofsd/seccomp.c        | 32 +++++++++++++++++--------
22c213
 tools/virtiofsd/seccomp.h        |  4 +++-
22c213
 5 files changed, 76 insertions(+), 13 deletions(-)
22c213
22c213
diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowlevel.h
22c213
index 0d61df8..f2750bc 100644
22c213
--- a/tools/virtiofsd/fuse_lowlevel.h
22c213
+++ b/tools/virtiofsd/fuse_lowlevel.h
22c213
@@ -1795,6 +1795,7 @@ struct fuse_cmdline_opts {
22c213
     int show_version;
22c213
     int show_help;
22c213
     int print_capabilities;
22c213
+    int syslog;
22c213
     unsigned int max_idle_threads;
22c213
 };
22c213
 
22c213
diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
22c213
index 5531425..9692ef9 100644
22c213
--- a/tools/virtiofsd/helper.c
22c213
+++ b/tools/virtiofsd/helper.c
22c213
@@ -54,6 +54,7 @@ static const struct fuse_opt fuse_helper_opts[] = {
22c213
     FUSE_HELPER_OPT("subtype=", nodefault_subtype),
22c213
     FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
22c213
     FUSE_HELPER_OPT("max_idle_threads=%u", max_idle_threads),
22c213
+    FUSE_HELPER_OPT("--syslog", syslog),
22c213
     FUSE_OPT_END
22c213
 };
22c213
 
22c213
@@ -138,6 +139,7 @@ void fuse_cmdline_help(void)
22c213
            "    -V   --version             print version\n"
22c213
            "    --print-capabilities       print vhost-user.json\n"
22c213
            "    -d   -o debug              enable debug output (implies -f)\n"
22c213
+           "    --syslog                   log to syslog (default stderr)\n"
22c213
            "    -f                         foreground operation\n"
22c213
            "    --daemonize                run in background\n"
22c213
            "    -o max_idle_threads        the maximum number of idle worker "
22c213
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
22c213
index c281d81..0372aca 100644
22c213
--- a/tools/virtiofsd/passthrough_ll.c
22c213
+++ b/tools/virtiofsd/passthrough_ll.c
22c213
@@ -58,6 +58,7 @@
22c213
 #include <sys/types.h>
22c213
 #include <sys/wait.h>
22c213
 #include <sys/xattr.h>
22c213
+#include <syslog.h>
22c213
 #include <unistd.h>
22c213
 
22c213
 #include "passthrough_helpers.h"
22c213
@@ -138,6 +139,7 @@ static const struct fuse_opt lo_opts[] = {
22c213
     { "norace", offsetof(struct lo_data, norace), 1 },
22c213
     FUSE_OPT_END
22c213
 };
22c213
+static bool use_syslog = false;
22c213
 
22c213
 static void unref_inode(struct lo_data *lo, struct lo_inode *inode, uint64_t n);
22c213
 
22c213
@@ -2262,11 +2264,12 @@ static void setup_mounts(const char *source)
22c213
  * Lock down this process to prevent access to other processes or files outside
22c213
  * source directory.  This reduces the impact of arbitrary code execution bugs.
22c213
  */
22c213
-static void setup_sandbox(struct lo_data *lo, struct fuse_session *se)
22c213
+static void setup_sandbox(struct lo_data *lo, struct fuse_session *se,
22c213
+                          bool enable_syslog)
22c213
 {
22c213
     setup_namespaces(lo, se);
22c213
     setup_mounts(lo->source);
22c213
-    setup_seccomp();
22c213
+    setup_seccomp(enable_syslog);
22c213
 }
22c213
 
22c213
 /* Raise the maximum number of open file descriptors */
22c213
@@ -2298,6 +2301,42 @@ static void setup_nofile_rlimit(void)
22c213
     }
22c213
 }
22c213
 
22c213
+static void log_func(enum fuse_log_level level, const char *fmt, va_list ap)
22c213
+{
22c213
+    if (use_syslog) {
22c213
+        int priority = LOG_ERR;
22c213
+        switch (level) {
22c213
+        case FUSE_LOG_EMERG:
22c213
+            priority = LOG_EMERG;
22c213
+            break;
22c213
+        case FUSE_LOG_ALERT:
22c213
+            priority = LOG_ALERT;
22c213
+            break;
22c213
+        case FUSE_LOG_CRIT:
22c213
+            priority = LOG_CRIT;
22c213
+            break;
22c213
+        case FUSE_LOG_ERR:
22c213
+            priority = LOG_ERR;
22c213
+            break;
22c213
+        case FUSE_LOG_WARNING:
22c213
+            priority = LOG_WARNING;
22c213
+            break;
22c213
+        case FUSE_LOG_NOTICE:
22c213
+            priority = LOG_NOTICE;
22c213
+            break;
22c213
+        case FUSE_LOG_INFO:
22c213
+            priority = LOG_INFO;
22c213
+            break;
22c213
+        case FUSE_LOG_DEBUG:
22c213
+            priority = LOG_DEBUG;
22c213
+            break;
22c213
+        }
22c213
+        vsyslog(priority, fmt, ap);
22c213
+    } else {
22c213
+        vfprintf(stderr, fmt, ap);
22c213
+    }
22c213
+}
22c213
+
22c213
 int main(int argc, char *argv[])
22c213
 {
22c213
     struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
22c213
@@ -2336,6 +2375,11 @@ int main(int argc, char *argv[])
22c213
     if (fuse_parse_cmdline(&args, &opts) != 0) {
22c213
         return 1;
22c213
     }
22c213
+    fuse_set_log_func(log_func);
22c213
+    use_syslog = opts.syslog;
22c213
+    if (use_syslog) {
22c213
+        openlog("virtiofsd", LOG_PID, LOG_DAEMON);
22c213
+    }
22c213
     if (opts.show_help) {
22c213
         printf("usage: %s [options]\n\n", argv[0]);
22c213
         fuse_cmdline_help();
22c213
@@ -2424,7 +2468,7 @@ int main(int argc, char *argv[])
22c213
     /* Must be before sandbox since it wants /proc */
22c213
     setup_capng();
22c213
 
22c213
-    setup_sandbox(&lo, se);
22c213
+    setup_sandbox(&lo, se, opts.syslog);
22c213
 
22c213
     /* Block until ctrl+c or fusermount -u */
22c213
     ret = virtio_loop(se);
22c213
diff --git a/tools/virtiofsd/seccomp.c b/tools/virtiofsd/seccomp.c
22c213
index 691fb63..2d9d4a7 100644
22c213
--- a/tools/virtiofsd/seccomp.c
22c213
+++ b/tools/virtiofsd/seccomp.c
22c213
@@ -107,11 +107,28 @@ static const int syscall_whitelist[] = {
22c213
     SCMP_SYS(writev),
22c213
 };
22c213
 
22c213
-void setup_seccomp(void)
22c213
+/* Syscalls used when --syslog is enabled */
22c213
+static const int syscall_whitelist_syslog[] = {
22c213
+    SCMP_SYS(sendto),
22c213
+};
22c213
+
22c213
+static void add_whitelist(scmp_filter_ctx ctx, const int syscalls[], size_t len)
22c213
 {
22c213
-    scmp_filter_ctx ctx;
22c213
     size_t i;
22c213
 
22c213
+    for (i = 0; i < len; i++) {
22c213
+        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) != 0) {
22c213
+            fuse_log(FUSE_LOG_ERR, "seccomp_rule_add syscall %d failed\n",
22c213
+                     syscalls[i]);
22c213
+            exit(1);
22c213
+        }
22c213
+    }
22c213
+}
22c213
+
22c213
+void setup_seccomp(bool enable_syslog)
22c213
+{
22c213
+    scmp_filter_ctx ctx;
22c213
+
22c213
 #ifdef SCMP_ACT_KILL_PROCESS
22c213
     ctx = seccomp_init(SCMP_ACT_KILL_PROCESS);
22c213
     /* Handle a newer libseccomp but an older kernel */
22c213
@@ -126,13 +143,10 @@ void setup_seccomp(void)
22c213
         exit(1);
22c213
     }
22c213
 
22c213
-    for (i = 0; i < G_N_ELEMENTS(syscall_whitelist); i++) {
22c213
-        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
22c213
-                             syscall_whitelist[i], 0) != 0) {
22c213
-            fuse_log(FUSE_LOG_ERR, "seccomp_rule_add syscall %d",
22c213
-                     syscall_whitelist[i]);
22c213
-            exit(1);
22c213
-        }
22c213
+    add_whitelist(ctx, syscall_whitelist, G_N_ELEMENTS(syscall_whitelist));
22c213
+    if (enable_syslog) {
22c213
+        add_whitelist(ctx, syscall_whitelist_syslog,
22c213
+                      G_N_ELEMENTS(syscall_whitelist_syslog));
22c213
     }
22c213
 
22c213
     /* libvhost-user calls this for post-copy migration, we don't need it */
22c213
diff --git a/tools/virtiofsd/seccomp.h b/tools/virtiofsd/seccomp.h
22c213
index 86bce72..d47c8ea 100644
22c213
--- a/tools/virtiofsd/seccomp.h
22c213
+++ b/tools/virtiofsd/seccomp.h
22c213
@@ -9,6 +9,8 @@
22c213
 #ifndef VIRTIOFSD_SECCOMP_H
22c213
 #define VIRTIOFSD_SECCOMP_H
22c213
 
22c213
-void setup_seccomp(void);
22c213
+#include <stdbool.h>
22c213
+
22c213
+void setup_seccomp(bool enable_syslog);
22c213
 
22c213
 #endif /* VIRTIOFSD_SECCOMP_H */
22c213
-- 
22c213
1.8.3.1
22c213