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