]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/log.c
github: Update for main branch
[mirror_lxc.git] / src / lxc / log.c
index 1dd277d964096f86ea3023bc00737c459820dc71..cdd11ff1c084c0cad8bb7f15b702092d0cf38c86 100644 (file)
@@ -1,9 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#endif
-#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
+#include "config.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <syslog.h>
 #include <unistd.h>
 
+#include "lxc.h"
+
 #include "caps.h"
-#include "config.h"
 #include "file_utils.h"
 #include "log.h"
-#include "lxccontainer.h"
 #include "memory_utils.h"
 #include "utils.h"
 
-#ifndef HAVE_STRLCPY
-#include "include/strlcpy.h"
+#if !HAVE_STRLCPY
+#include "strlcpy.h"
 #endif
 
 #if HAVE_DLOG
@@ -44,9 +42,9 @@
 #define LXC_LOG_TIME_SIZE ((INTTYPE_TO_STRLEN(uint64_t)) * 2)
 
 int lxc_log_fd = -EBADF;
-static int syslog_enable = 0;
-int lxc_quiet_specified;
-int lxc_log_use_global_fd;
+static bool wants_syslog = false;
+static int lxc_quiet_specified;
+bool lxc_log_use_global_fd = false;
 static int lxc_loglevel_specified;
 
 static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc";
@@ -82,7 +80,7 @@ static int lxc_log_priority_to_syslog(int priority)
        return LOG_NOTICE;
 }
 
-static const char *lxc_log_get_container_name()
+static const char *lxc_log_get_container_name(void)
 {
 #ifndef NO_LXC_CONF
        if (current_config && !log_vmname)
@@ -92,6 +90,20 @@ static const char *lxc_log_get_container_name()
        return log_vmname;
 }
 
+int lxc_log_get_fd(void)
+{
+       int fd_log = -EBADF;
+
+#ifndef NO_LXC_CONF
+       if (current_config && !lxc_log_use_global_fd)
+               fd_log = current_config->logfd;
+#endif
+       if (fd_log < 0)
+               fd_log = lxc_log_fd;
+
+       return fd_log;
+}
+
 static char *lxc_log_get_va_msg(struct lxc_log_event *event)
 {
        __do_free char *msg = NULL;
@@ -128,7 +140,7 @@ static int log_append_syslog(const struct lxc_log_appender *appender,
        __do_free char *msg = NULL;
        const char *log_container_name;
 
-       if (!syslog_enable)
+       if (!wants_syslog)
                return 0;
 
        log_container_name = lxc_log_get_container_name();
@@ -266,19 +278,19 @@ static int lxc_unix_epoch_to_utc(char *buf, size_t bufsize, const struct timespe
        seconds = (time->tv_sec - d_in_s - h_in_s - (minutes * 60));
 
        /* Make string from nanoseconds. */
-       ret = snprintf(nanosec, sizeof(nanosec), "%"PRId64, (int64_t)time->tv_nsec);
-       if (ret < 0 || (size_t)ret >= sizeof(nanosec))
+       ret = strnprintf(nanosec, sizeof(nanosec), "%"PRId64, (int64_t)time->tv_nsec);
+       if (ret < 0)
                return ret_errno(EIO);
 
        /*
         * Create final timestamp for the log and shorten nanoseconds to 3
         * digit precision.
         */
-       ret = snprintf(buf, bufsize,
+       ret = strnprintf(buf, bufsize,
                       "%" PRId64 "%02" PRId64 "%02" PRId64 "%02" PRId64
                       "%02" PRId64 "%02" PRId64 ".%.3s",
                       year, month, day, hours, minutes, seconds, nanosec);
-       if (ret < 0 || (size_t)ret >= bufsize)
+       if (ret < 0)
                return ret_errno(EIO);
 
        return 0;
@@ -332,6 +344,10 @@ static int log_append_logfile(const struct lxc_log_appender *appender,
        if (ret)
                return ret;
 
+       /*
+        * We allow truncation here which is why we use snprintf() directly
+        * instead of strnprintf().
+        */
        n = snprintf(buffer, sizeof(buffer),
                     "%s%s%s %s %-8s %s - %s:%s:%d - ",
                     log_prefix,
@@ -471,6 +487,9 @@ static int build_dir(const char *name)
        __do_free char *n = NULL;
        char *e, *p;
 
+       if (is_empty_string(name))
+               return ret_errno(EINVAL);
+
        /* Make copy of the string since we'll be modifying it. */
        n = strdup(name);
        if (!n)
@@ -484,7 +503,14 @@ static int build_dir(const char *name)
                        continue;
                *p = '\0';
 
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
                ret = lxc_unpriv(mkdir(n, 0755));
+#else
+               if (RUN_ON_OSS_FUZZ || is_in_comm("fuzz-lxc-") > 0)
+                       ret = errno = EEXIST;
+               else
+                       ret = lxc_unpriv(mkdir(n, 0755));
+#endif /*!FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
                *p = '/';
                if (ret && errno != EEXIST)
                        return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", n);
@@ -495,10 +521,15 @@ static int build_dir(const char *name)
 
 static int log_open(const char *name)
 {
+       int newfd = -EBADF;
        __do_close int fd = -EBADF;
-       int newfd;
 
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0660));
+#else
+       if (!RUN_ON_OSS_FUZZ && is_in_comm("fuzz-lxc-") <= 0)
+               fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0660));
+#endif /* !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
        if (fd < 0)
                return log_error_errno(-errno, errno, "Failed to open log file \"%s\"", name);
 
@@ -508,7 +539,6 @@ static int log_open(const char *name)
        newfd = fcntl(fd, F_DUPFD_CLOEXEC, STDERR_FILENO);
        if (newfd < 0)
                return log_error_errno(-errno, errno, "Failed to dup log fd %d", fd);
-
        return newfd;
 }
 
@@ -558,10 +588,10 @@ static char *build_log_path(const char *name, const char *lxcpath)
                return ret_set_errno(NULL, ENOMEM);
 
        if (use_dir)
-               ret = snprintf(p, len, "%s/%s/%s.log", lxcpath, name, name);
+               ret = strnprintf(p, len, "%s/%s/%s.log", lxcpath, name, name);
        else
-               ret = snprintf(p, len, "%s/%s.log", lxcpath, name);
-       if (ret < 0 || (size_t)ret >= len)
+               ret = strnprintf(p, len, "%s/%s.log", lxcpath, name);
+       if (ret < 0)
                return ret_set_errno(NULL, EIO);
 
        return move_ptr(p);
@@ -581,7 +611,7 @@ static int __lxc_log_set_file(const char *fname, int create_dirs)
        if (lxc_log_fd >= 0)
                lxc_log_close();
 
-       if (!fname)
+       if (is_empty_string(fname))
                return ret_errno(EINVAL);
 
        if (strlen(fname) == 0) {
@@ -652,14 +682,14 @@ int lxc_log_init(struct lxc_log *log)
                log_vmname = strdup(log->name);
 
        if (log->file) {
-               if (strcmp(log->file, "none") == 0)
+               if (strequal(log->file, "none"))
                        return 0;
 
                ret = __lxc_log_set_file(log->file, 1);
                if (ret < 0)
                        return log_error_errno(-1, errno, "Failed to enable logfile");
 
-               lxc_log_use_global_fd = 1;
+               lxc_log_use_global_fd = true;
        } else {
                /* if no name was specified, there nothing to do */
                if (!log->name)
@@ -671,7 +701,7 @@ int lxc_log_init(struct lxc_log *log)
                        log->lxcpath = LOGPATH;
 
                /* try LOGPATH if lxcpath is the default for the privileged containers */
-               if (!geteuid() && strcmp(LXCPATH, log->lxcpath) == 0)
+               if (!geteuid() && strequal(LXCPATH, log->lxcpath))
                        ret = _lxc_log_set_file(log->name, NULL, 0);
 
                /* try in lxcpath */
@@ -738,9 +768,14 @@ int lxc_log_syslog(int facility)
        return 0;
 }
 
-inline void lxc_log_enable_syslog(void)
+void lxc_log_syslog_enable(void)
+{
+       wants_syslog = true;
+}
+
+void lxc_log_syslog_disable(void)
 {
-       syslog_enable = 1;
+       wants_syslog = false;
 }
 
 /*
@@ -757,9 +792,18 @@ int lxc_log_set_level(int *dest, int level)
        return 0;
 }
 
-inline int lxc_log_get_level(void)
+int lxc_log_get_level(void)
 {
-       return lxc_log_category_lxc.priority;
+       int level = LXC_LOG_LEVEL_NOTSET;
+
+#ifndef NO_LXC_CONF
+       if (current_config)
+               level = current_config->loglevel;
+#endif
+       if (level == LXC_LOG_LEVEL_NOTSET)
+               level = lxc_log_category_lxc.priority;
+
+       return level;
 }
 
 bool lxc_log_has_valid_level(void)
@@ -783,13 +827,15 @@ int lxc_log_set_file(int *fd, const char *fname)
        if (*fd >= 0)
                close_prot_errno_disarm(*fd);
 
+       if (is_empty_string(fname))
+               return ret_errno(EINVAL);
+
        if (build_dir(fname))
                return -errno;
 
        *fd = log_open(fname);
        if (*fd < 0)
                return -errno;
-
        return 0;
 }
 
@@ -809,7 +855,7 @@ inline const char *lxc_log_get_prefix(void)
        return log_prefix;
 }
 
-inline void lxc_log_options_no_override()
+inline void lxc_log_options_no_override(void)
 {
        lxc_quiet_specified = 1;
        lxc_loglevel_specified = 1;