]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/confile.c
secure coding: #2 strcpy => strlcpy
[mirror_lxc.git] / src / lxc / confile.c
index a9db536307d483967b210d52a7115f23ad0d16d3..d019c898484ff9843d70440b3795ae2c02c0b80a 100644 (file)
 #include <sys/personality.h>
 #endif
 
+#ifndef HAVE_STRLCPY
+#include "include/strlcpy.h"
+#endif
+
 lxc_log_define(lxc_confile, lxc);
 
 #define lxc_config_define(name)                                                \
@@ -82,11 +86,11 @@ lxc_config_define(cap_keep);
 lxc_config_define(cgroup_controller);
 lxc_config_define(cgroup2_controller);
 lxc_config_define(cgroup_dir);
-lxc_config_define(console_logfile);
-lxc_config_define(console_rotate);
-lxc_config_define(console_buffer_logfile);
 lxc_config_define(console_buffer_size);
+lxc_config_define(console_logfile);
 lxc_config_define(console_path);
+lxc_config_define(console_rotate);
+lxc_config_define(console_size);
 lxc_config_define(environment);
 lxc_config_define(ephemeral);
 lxc_config_define(execute_cmd);
@@ -155,11 +159,11 @@ static struct lxc_config_t config[] = {
        { "lxc.cgroup2",                   set_config_cgroup2_controller,          get_config_cgroup2_controller,          clr_config_cgroup2_controller,        },
        { "lxc.cgroup.dir",                set_config_cgroup_dir,                  get_config_cgroup_dir,                  clr_config_cgroup_dir,                },
        { "lxc.cgroup",                    set_config_cgroup_controller,           get_config_cgroup_controller,           clr_config_cgroup_controller,         },
-       { "lxc.console.buffer.logfile",    set_config_console_buffer_logfile,      get_config_console_buffer_logfile,      clr_config_console_buffer_logfile,    },
        { "lxc.console.buffer.size",       set_config_console_buffer_size,         get_config_console_buffer_size,         clr_config_console_buffer_size,       },
        { "lxc.console.logfile",           set_config_console_logfile,             get_config_console_logfile,             clr_config_console_logfile,           },
        { "lxc.console.path",              set_config_console_path,                get_config_console_path,                clr_config_console_path,              },
        { "lxc.console.rotate",            set_config_console_rotate,              get_config_console_rotate,              clr_config_console_rotate,            },
+       { "lxc.console.size",              set_config_console_size,                get_config_console_size,                clr_config_console_size,              },
        { "lxc.environment",               set_config_environment,                 get_config_environment,                 clr_config_environment,               },
        { "lxc.ephemeral",                 set_config_ephemeral,                   get_config_ephemeral,                   clr_config_ephemeral,                 },
        { "lxc.execute.cmd",               set_config_execute_cmd,                 get_config_execute_cmd,                 clr_config_execute_cmd,               },
@@ -628,8 +632,12 @@ static int set_config_net_ipv4_address(const char *key, const char *value,
        /* No prefix specified, determine it from the network class. */
        if (prefix) {
                ret = lxc_safe_uint(prefix, &inetdev->prefix);
-               if (ret < 0)
+               if (ret < 0) {
+                       free(inetdev);
+                       free(list);
+                       free(addr);
                        return -1;
+               }
        } else {
                inetdev->prefix = config_ip_prefix(&inetdev->addr);
        }
@@ -974,14 +982,19 @@ static int set_config_personality(const char *key, const char *value,
 static int set_config_pty_max(const char *key, const char *value,
                              struct lxc_conf *lxc_conf, void *data)
 {
+       int ret;
+       unsigned int max = 0;
+
        if (lxc_config_value_empty(value)) {
-               lxc_conf->pts = 0;
+               lxc_conf->pty_max = 0;
                return 0;
        }
 
-       if (lxc_safe_uint(value, &lxc_conf->pts) < 0)
+       ret = lxc_safe_uint(value, &max);
+       if (ret < 0)
                return -1;
 
+       lxc_conf->pty_max = max;
        return 0;
 }
 
@@ -1096,7 +1109,21 @@ static int set_config_environment(const char *key, const char *value,
        if (!list_item)
                goto on_error;
 
-       list_item->elem = strdup(value);
+       if (!strchr(value, '=')) {
+               const char *env_val;
+               const char *env_key = value;
+               const char *env_var[3] = {0};
+
+               env_val = getenv(env_key);
+               if (!env_val)
+                       goto on_error;
+
+               env_var[0] = env_key;
+               env_var[1] = env_val;
+               list_item->elem = lxc_string_join("=", env_var, false);
+       } else {
+               list_item->elem = strdup(value);
+       }
 
        if (!list_item->elem)
                goto on_error;
@@ -1113,18 +1140,26 @@ on_error:
 static int set_config_tty_max(const char *key, const char *value,
                              struct lxc_conf *lxc_conf, void *data)
 {
+       int ret;
+       unsigned int nbtty = 0;
+
        if (lxc_config_value_empty(value)) {
-               lxc_conf->tty = 0;
+               lxc_conf->ttys.max = 0;
                return 0;
        }
 
-       return lxc_safe_uint(value, &lxc_conf->tty);
+       ret = lxc_safe_uint(value, &nbtty);
+       if (ret < 0)
+               return -1;
+
+       lxc_conf->ttys.max = nbtty;
+       return 0;
 }
 
 static int set_config_tty_dir(const char *key, const char *value,
                             struct lxc_conf *lxc_conf, void *data)
 {
-       return set_config_string_item_max(&lxc_conf->ttydir, value,
+       return set_config_string_item_max(&lxc_conf->ttys.dir, value,
                                          NAME_MAX + 1);
 }
 
@@ -1961,11 +1996,51 @@ static int set_config_console_buffer_size(const char *key, const char *value,
        return 0;
 }
 
-static int set_config_console_buffer_logfile(const char *key, const char *value,
-                                            struct lxc_conf *lxc_conf,
-                                            void *data)
+static int set_config_console_size(const char *key, const char *value,
+                                  struct lxc_conf *lxc_conf, void *data)
 {
-       return set_config_path_item(&lxc_conf->console.buffer_log_file, value);
+       int ret;
+       int64_t size;
+       uint64_t log_size, pgsz;
+
+       if (lxc_config_value_empty(value)) {
+               lxc_conf->console.log_size = 0;
+               return 0;
+       }
+
+       /* If the user specified "auto" the default log size is 2^17 = 128 Kib */
+       if (!strcmp(value, "auto")) {
+               lxc_conf->console.log_size = 1 << 17;
+               return 0;
+       }
+
+       ret = parse_byte_size_string(value, &size);
+       if (ret < 0)
+               return -1;
+
+       if (size < 0)
+               return -EINVAL;
+
+       /* must be at least a page size */
+       pgsz = lxc_getpagesize();
+       if ((uint64_t)size < pgsz) {
+               NOTICE("Requested ringbuffer size for the console is %" PRId64
+                      " but must be at least %" PRId64
+                      " bytes. Setting ringbuffer size to %" PRId64 " bytes",
+                      size, pgsz, pgsz);
+               size = pgsz;
+       }
+
+       log_size = lxc_find_next_power2((uint64_t)size);
+       if (log_size == 0)
+               return -EINVAL;
+
+       if (log_size != size)
+               NOTICE("Passed size was not a power of 2. Rounding log size to "
+                      "next power of two: %" PRIu64 " bytes", log_size);
+
+       lxc_conf->console.log_size = log_size;
+       return 0;
 }
 
 int append_unexp_config_line(const char *line, struct lxc_conf *conf)
@@ -2009,8 +2084,6 @@ static int do_includedir(const char *dirp, struct lxc_conf *lxc_conf)
 
        while ((direntp = readdir(dir))) {
                const char *fnam;
-               if (!direntp)
-                       break;
 
                fnam = direntp->d_name;
                if (!strcmp(fnam, "."))
@@ -2126,7 +2199,7 @@ static int set_config_uts_name(const char *key, const char *value,
                return -1;
        }
 
-       strcpy(utsname->nodename, value);
+       (void)strlcpy(utsname->nodename, value, sizeof(utsname->nodename));
        free(lxc_conf->utsname);
        lxc_conf->utsname = utsname;
 
@@ -2334,7 +2407,7 @@ int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include)
        if (!conf->rcfile)
                conf->rcfile = strdup(file);
 
-       return lxc_file_for_each_line(file, parse_line, &c);
+       return lxc_file_for_each_line_mmap(file, parse_line, &c);
 }
 
 int lxc_config_define_add(struct lxc_list *defines, char *arg)
@@ -2377,57 +2450,59 @@ signed long lxc_config_parse_arch(const char *arch)
                char *name;
                unsigned long per;
        } pername[] = {
-           { "x86",       PER_LINUX32 },
-           { "linux32",   PER_LINUX32 },
+           { "arm",       PER_LINUX32 },
+           { "armel",     PER_LINUX32 },
+           { "armhf",     PER_LINUX32 },
+           { "armv7l",    PER_LINUX32 },
+           { "athlon",    PER_LINUX32 },
            { "i386",      PER_LINUX32 },
            { "i486",      PER_LINUX32 },
            { "i586",      PER_LINUX32 },
            { "i686",      PER_LINUX32 },
-           { "athlon",    PER_LINUX32 },
+           { "linux32",   PER_LINUX32 },
            { "mips",      PER_LINUX32 },
            { "mipsel",    PER_LINUX32 },
            { "ppc",       PER_LINUX32 },
-           { "arm",       PER_LINUX32 },
-           { "armv7l",    PER_LINUX32 },
-           { "armhf",     PER_LINUX32 },
-           { "armel",     PER_LINUX32 },
            { "powerpc",   PER_LINUX32 },
-           { "linux64",   PER_LINUX   },
-           { "x86_64",    PER_LINUX   },
+           { "x86",       PER_LINUX32 },
            { "amd64",     PER_LINUX   },
+           { "arm64",     PER_LINUX   },
+           { "linux64",   PER_LINUX   },
            { "mips64",    PER_LINUX   },
            { "mips64el",  PER_LINUX   },
            { "ppc64",     PER_LINUX   },
-           { "ppc64le",   PER_LINUX   },
            { "ppc64el",   PER_LINUX   },
+           { "ppc64le",   PER_LINUX   },
            { "powerpc64", PER_LINUX   },
            { "s390x",     PER_LINUX   },
-           { "aarch64",   PER_LINUX   },
-           { "arm64",     PER_LINUX   },
+           { "x86_64",    PER_LINUX   },
        };
        size_t len = sizeof(pername) / sizeof(pername[0]);
 
-       for (i = 0; i < len; i++) {
+       for (i = 0; i < len; i++)
                if (!strcmp(pername[i].name, arch))
                        return pername[i].per;
-       }
 #endif
 
        return -1;
 }
 
 /* Write out a configuration file. */
-void write_config(FILE *fout, struct lxc_conf *c)
+int write_config(int fd, const struct lxc_conf *conf)
 {
        int ret;
-       size_t len = c->unexpanded_len;
+       size_t len = conf->unexpanded_len;
 
-       if (!len)
-               return;
+       if (len == 0)
+               return 0;
 
-       ret = fwrite(c->unexpanded_config, 1, len, fout);
-       if (ret != len)
+       ret = lxc_write_nointr(fd, conf->unexpanded_config, len);
+       if (ret < 0) {
                SYSERROR("Failed to write configuration file");
+               return -1;
+       }
+
+       return 0;
 }
 
 bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
@@ -2538,17 +2613,16 @@ bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath,
                if (p >= lend)
                        goto next;
 
-               /* Whenever an lxc.mount.entry entry is found in a line we check
-               *  if the substring " overlay" or the substring " aufs" is
-               *  present before doing any further work. We check for "
-               *  overlay" and " aufs" since both substrings need to have at
-               *  least one space before them in a valid overlay
+               /* Whenever a lxc.mount.entry entry is found in a line we check
+               *  if the substring "overlay" is present before doing any
+               *  further work. We check for "overlay" because substrings need
+               *  to have at least one space before them in a valid overlay
                *  lxc.mount.entry (/A B overlay).  When the space before is
                *  missing it is very likely that these substrings are part of a
                *  path or something else. (Checking q >= lend ensures that we
                *  only count matches in the current line.) */
-               if ((!(q = strstr(p, " overlay")) || q >= lend) &&
-                   (!(q = strstr(p, " aufs")) || q >= lend))
+               q = strstr(p, " overlay");
+               if (!q || q >= lend)
                        goto next;
 
                if (!(q = strstr(p, olddir)) || (q >= lend))
@@ -2856,19 +2930,19 @@ static int get_config_personality(const char *key, char *retv, int inlen,
 static int get_config_pty_max(const char *key, char *retv, int inlen,
                              struct lxc_conf *c, void *data)
 {
-       return lxc_get_conf_int(c, retv, inlen, c->pts);
+       return lxc_get_conf_size_t(c, retv, inlen, c->pty_max);
 }
 
 static int get_config_tty_max(const char *key, char *retv, int inlen,
                              struct lxc_conf *c, void *data)
 {
-       return lxc_get_conf_int(c, retv, inlen, c->tty);
+       return lxc_get_conf_size_t(c, retv, inlen, c->ttys.max);
 }
 
 static int get_config_tty_dir(const char *key, char *retv, int inlen,
                             struct lxc_conf *c, void *data)
 {
-       return lxc_get_conf_str(retv, inlen, c->ttydir);
+       return lxc_get_conf_str(retv, inlen, c->ttys.dir);
 }
 
 static int get_config_apparmor_profile(const char *key, char *retv, int inlen,
@@ -3294,13 +3368,13 @@ static int get_config_console_buffer_size(const char *key, char *retv,
        return lxc_get_conf_uint64(c, retv, inlen, c->console.buffer_size);
 }
 
-static int get_config_console_buffer_logfile(const char *key, char *retv,
-                                            int inlen, struct lxc_conf *c,
-                                            void *data)
+static int get_config_console_size(const char *key, char *retv, int inlen,
+                                  struct lxc_conf *c, void *data)
 {
-       return lxc_get_conf_str(retv, inlen, c->console.buffer_log_file);
+       return lxc_get_conf_uint64(c, retv, inlen, c->console.log_size);
 }
 
+
 static int get_config_seccomp_profile(const char *key, char *retv, int inlen,
                                      struct lxc_conf *c, void *data)
 {
@@ -3633,22 +3707,22 @@ static inline int clr_config_personality(const char *key, struct lxc_conf *c,
 static inline int clr_config_pty_max(const char *key, struct lxc_conf *c,
                                     void *data)
 {
-       c->pts = 0;
+       c->pty_max = 0;
        return 0;
 }
 
 static inline int clr_config_tty_max(const char *key, struct lxc_conf *c,
                                     void *data)
 {
-       c->tty = 0;
+       c->ttys.tty = 0;
        return 0;
 }
 
 static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c,
                                    void *data)
 {
-       free(c->ttydir);
-       c->ttydir = NULL;
+       free(c->ttys.dir);
+       c->ttys.dir = NULL;
        return 0;
 }
 
@@ -3836,12 +3910,10 @@ static inline int clr_config_console_buffer_size(const char *key,
        return 0;
 }
 
-static inline int clr_config_console_buffer_logfile(const char *key,
-                                                   struct lxc_conf *c,
-                                                   void *data)
+static inline int clr_config_console_size(const char *key, struct lxc_conf *c,
+                                         void *data)
 {
-       free(c->console.buffer_log_file);
-       c->console.buffer_log_file = NULL;
+       c->console.log_size = 0;
        return 0;
 }