Blame 0067-virtiofsd-add-syslog-command-line-option.patch

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