Unverified Commit 244a5017 by Stéphane Graber Committed by GitHub

Merge pull request #3665 from brauner/2021-02-11/fixes

tree-wide: fixes
parents ff4e4629 af00ba8b
...@@ -116,8 +116,8 @@ static pid_t pidfd_get_pid(int dfd_init_pid, int pidfd) ...@@ -116,8 +116,8 @@ static pid_t pidfd_get_pid(int dfd_init_pid, int pidfd)
if (dfd_init_pid < 0 || pidfd < 0) if (dfd_init_pid < 0 || pidfd < 0)
return ret_errno(EBADF); return ret_errno(EBADF);
ret = snprintf(path + STRLITERALLEN("fdinfo/"), INTTYPE_TO_STRLEN(int), "%d", pidfd); ret = strnprintf(path + STRLITERALLEN("fdinfo/"), INTTYPE_TO_STRLEN(int), "%d", pidfd);
if (ret < 0 || ret > (size_t)INTTYPE_TO_STRLEN(int)) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
f = fdopen_at(dfd_init_pid, path, "re", PROTECT_OPEN, PROTECT_LOOKUP_BENEATH); f = fdopen_at(dfd_init_pid, path, "re", PROTECT_OPEN, PROTECT_LOOKUP_BENEATH);
...@@ -403,8 +403,8 @@ static int get_attach_context(struct attach_context *ctx, ...@@ -403,8 +403,8 @@ static int get_attach_context(struct attach_context *ctx,
if (ctx->init_pid < 0) if (ctx->init_pid < 0)
return log_error(-1, "Failed to get init pid"); return log_error(-1, "Failed to get init pid");
ret = snprintf(path, sizeof(path), "/proc/%d", ctx->init_pid); ret = strnprintf(path, sizeof(path), "/proc/%d", ctx->init_pid);
if (ret < 0 || ret >= sizeof(path)) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
ctx->dfd_init_pid = open_at(-EBADF, path, ctx->dfd_init_pid = open_at(-EBADF, path,
...@@ -947,8 +947,8 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -947,8 +947,8 @@ static char *lxc_attach_getpwshell(uid_t uid)
} }
/* Finish argument list. */ /* Finish argument list. */
ret = snprintf(uid_buf, sizeof(uid_buf), "%ld", (long)uid); ret = strnprintf(uid_buf, sizeof(uid_buf), "%ld", (long)uid);
if (ret <= 0 || ret >= sizeof(uid_buf)) if (ret <= 0)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
/* Try to run getent program. */ /* Try to run getent program. */
......
...@@ -266,8 +266,8 @@ static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits) ...@@ -266,8 +266,8 @@ static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
if (!is_set(i, bitarr)) if (!is_set(i, bitarr))
continue; continue;
ret = snprintf(numstr, sizeof(numstr), "%zu", i); ret = strnprintf(numstr, sizeof(numstr), "%zu", i);
if (ret < 0 || (size_t)ret >= sizeof(numstr)) if (ret < 0)
return NULL; return NULL;
ret = lxc_append_string(&cpulist, numstr); ret = lxc_append_string(&cpulist, numstr);
...@@ -1053,8 +1053,8 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops, ...@@ -1053,8 +1053,8 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
} }
conf = handler->conf; conf = handler->conf;
len = snprintf(pidstr, sizeof(pidstr), "%d", handler->monitor_pid); len = strnprintf(pidstr, sizeof(pidstr), "%d", handler->monitor_pid);
if (len < 0 || (size_t)len >= sizeof(pidstr)) if (len < 0)
return; return;
for (int i = 0; ops->hierarchies[i]; i++) { for (int i = 0; ops->hierarchies[i]; i++) {
...@@ -1471,9 +1471,15 @@ __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops, ...@@ -1471,9 +1471,15 @@ __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops,
if (!handler || !handler->conf) if (!handler || !handler->conf)
return ret_set_errno(false, EINVAL); return ret_set_errno(false, EINVAL);
monitor_len = snprintf(monitor, sizeof(monitor), "%d", handler->monitor_pid); monitor_len = strnprintf(monitor, sizeof(monitor), "%d", handler->monitor_pid);
if (handler->transient_pid > 0) if (monitor_len < 0)
transient_len = snprintf(transient, sizeof(transient), "%d", handler->transient_pid); return false;
if (handler->transient_pid > 0) {
transient_len = strnprintf(transient, sizeof(transient), "%d", handler->transient_pid);
if (transient_len < 0)
return false;
}
for (int i = 0; ops->hierarchies[i]; i++) { for (int i = 0; ops->hierarchies[i]; i++) {
struct hierarchy *h = ops->hierarchies[i]; struct hierarchy *h = ops->hierarchies[i];
...@@ -1526,7 +1532,9 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, ...@@ -1526,7 +1532,9 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops,
if (!handler || !handler->conf) if (!handler || !handler->conf)
return ret_set_errno(false, EINVAL); return ret_set_errno(false, EINVAL);
len = snprintf(pidstr, sizeof(pidstr), "%d", handler->pid); len = strnprintf(pidstr, sizeof(pidstr), "%d", handler->pid);
if (len < 0)
return false;
for (int i = 0; ops->hierarchies[i]; i++) { for (int i = 0; ops->hierarchies[i]; i++) {
struct hierarchy *h = ops->hierarchies[i]; struct hierarchy *h = ops->hierarchies[i];
...@@ -2283,9 +2291,9 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t ...@@ -2283,9 +2291,9 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t
if (ret < 0 && errno != EEXIST) if (ret < 0 && errno != EEXIST)
return log_error_errno(-errno, errno, "Failed to create leaf cgroup \".lxc\""); return log_error_errno(-errno, errno, "Failed to create leaf cgroup \".lxc\"");
pidstr_len = snprintf(pidstr, sizeof(pidstr), INT64_FMT, (int64_t)pid); pidstr_len = strnprintf(pidstr, sizeof(pidstr), INT64_FMT, (int64_t)pid);
if (pidstr_len < 0 || (size_t)pidstr_len >= sizeof(pidstr)) if (pidstr_len < 0)
return ret_errno(EIO); return pidstr_len;
ret = lxc_writeat(unified_fd, ".lxc/cgroup.procs", pidstr, pidstr_len); ret = lxc_writeat(unified_fd, ".lxc/cgroup.procs", pidstr, pidstr_len);
if (ret < 0) if (ret < 0)
...@@ -2302,9 +2310,9 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t ...@@ -2302,9 +2310,9 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t
char attach_cgroup[STRLITERALLEN(".lxc-/cgroup.procs") + INTTYPE_TO_STRLEN(int) + 1]; char attach_cgroup[STRLITERALLEN(".lxc-/cgroup.procs") + INTTYPE_TO_STRLEN(int) + 1];
char *slash = attach_cgroup; char *slash = attach_cgroup;
ret = snprintf(attach_cgroup, sizeof(attach_cgroup), ".lxc-%d/cgroup.procs", idx); ret = strnprintf(attach_cgroup, sizeof(attach_cgroup), ".lxc-%d/cgroup.procs", idx);
if (ret < 0 || (size_t)ret >= sizeof(attach_cgroup)) if (ret < 0)
return ret_errno(EIO); return ret;
/* /*
* This shouldn't really happen but the compiler might complain * This shouldn't really happen but the compiler might complain
...@@ -2510,8 +2518,8 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, ...@@ -2510,8 +2518,8 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops,
if (!ops->hierarchies) if (!ops->hierarchies)
return true; return true;
len = snprintf(pidstr, sizeof(pidstr), "%d", pid); len = strnprintf(pidstr, sizeof(pidstr), "%d", pid);
if (len < 0 || (size_t)len >= sizeof(pidstr)) if (len < 0)
return false; return false;
for (int i = 0; ops->hierarchies[i]; i++) { for (int i = 0; ops->hierarchies[i]; i++) {
...@@ -2827,11 +2835,13 @@ static int convert_devpath(const char *invalue, char *dest) ...@@ -2827,11 +2835,13 @@ static int convert_devpath(const char *invalue, char *dest)
if (ret < 0) if (ret < 0)
return -1; return -1;
ret = snprintf(dest, 50, "%c %d:%d %s", device.type, device.major, ret = strnprintf(dest, 50, "%c %d:%d %s", device.type, device.major,
device.minor, device.access); device.minor, device.access);
if (ret < 0 || ret >= 50) if (ret < 0)
return log_error_errno(-1, ENAMETOOLONG, "Error on configuration value \"%c %d:%d %s\" (max 50 chars)", return log_error_errno(ret, -ret,
device.type, device.major, device.minor, device.access); "Error on configuration value \"%c %d:%d %s\" (max 50 chars)",
device.type, device.major, device.minor,
device.access);
return 0; return 0;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "memory_utils.h" #include "memory_utils.h"
#include "monitor.h" #include "monitor.h"
#include "state.h" #include "state.h"
#include "string_utils.h"
#include "utils.h" #include "utils.h"
lxc_log_define(commands_utils, lxc); lxc_log_define(commands_utils, lxc);
...@@ -104,8 +105,8 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, ...@@ -104,8 +105,8 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen,
name = ""; name = "";
if (hashed_sock_name != NULL) { if (hashed_sock_name != NULL) {
ret = snprintf(offset, len, "lxc/%s/%s", hashed_sock_name, suffix); ret = strnprintf(offset, len, "lxc/%s/%s", hashed_sock_name, suffix);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return log_error_errno(-1, errno, "Failed to create abstract socket name"); return log_error_errno(-1, errno, "Failed to create abstract socket name");
return 0; return 0;
} }
...@@ -116,6 +117,10 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, ...@@ -116,6 +117,10 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen,
return log_error(-1, "Failed to allocate memory"); return log_error(-1, "Failed to allocate memory");
} }
/*
* Here we allow exceeding the buffer because we're falling back to
* hashing. So we're not using strnprintf() here.
*/
ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix); ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, "Failed to create abstract socket name"); return log_error_errno(-1, errno, "Failed to create abstract socket name");
...@@ -127,13 +132,13 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, ...@@ -127,13 +132,13 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen,
if (ret >= len) { if (ret >= len) {
tmplen = strlen(name) + strlen(lxcpath) + 2; tmplen = strlen(name) + strlen(lxcpath) + 2;
tmppath = must_realloc(NULL, tmplen); tmppath = must_realloc(NULL, tmplen);
ret = snprintf(tmppath, tmplen, "%s/%s", lxcpath, name); ret = strnprintf(tmppath, tmplen, "%s/%s", lxcpath, name);
if (ret < 0 || (size_t)ret >= tmplen) if (ret < 0)
return log_error_errno(-1, errno, "Failed to create abstract socket name"); return log_error_errno(-1, errno, "Failed to create abstract socket name");
hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT); hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
ret = snprintf(offset, len, "lxc/%016" PRIx64 "/%s", hash, suffix); ret = strnprintf(offset, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return log_error_errno(-1, errno, "Failed to create abstract socket name"); return log_error_errno(-1, errno, "Failed to create abstract socket name");
} }
......
...@@ -2574,8 +2574,8 @@ static int do_includedir(const char *dirp, struct lxc_conf *lxc_conf) ...@@ -2574,8 +2574,8 @@ static int do_includedir(const char *dirp, struct lxc_conf *lxc_conf)
if (len < 6 || strncmp(fnam + len - 5, ".conf", 5) != 0) if (len < 6 || strncmp(fnam + len - 5, ".conf", 5) != 0)
continue; continue;
len = snprintf(path, PATH_MAX, "%s/%s", dirp, fnam); len = strnprintf(path, sizeof(path), "%s/%s", dirp, fnam);
if (len < 0 || len >= PATH_MAX) if (len < 0)
return ret_errno(EIO); return ret_errno(EIO);
ret = lxc_config_read(path, lxc_conf, true); ret = lxc_config_read(path, lxc_conf, true);
...@@ -3161,10 +3161,10 @@ bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key, ...@@ -3161,10 +3161,10 @@ bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
tmp = must_realloc(NULL, len); tmp = must_realloc(NULL, len);
if (lxc_config_value_empty(v)) if (lxc_config_value_empty(v))
ret = snprintf(tmp, len, "%s =", key); ret = strnprintf(tmp, len, "%s =", key);
else else
ret = snprintf(tmp, len, "%s = %s", key, v); ret = strnprintf(tmp, len, "%s = %s", key, v);
if (ret < 0 || ret >= len) if (ret < 0)
return false; return false;
/* Save the line verbatim into unexpanded_conf */ /* Save the line verbatim into unexpanded_conf */
...@@ -3229,16 +3229,14 @@ bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath, ...@@ -3229,16 +3229,14 @@ bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath,
olddirlen = strlen(ovldir) + strlen(oldpath) + strlen(oldname) + 2; olddirlen = strlen(ovldir) + strlen(oldpath) + strlen(oldname) + 2;
olddir = must_realloc(NULL, olddirlen + 1); olddir = must_realloc(NULL, olddirlen + 1);
ret = snprintf(olddir, olddirlen + 1, "%s=%s/%s", ovldir, oldpath, ret = strnprintf(olddir, olddirlen + 1, "%s=%s/%s", ovldir, oldpath, oldname);
oldname); if (ret < 0)
if (ret < 0 || ret >= olddirlen + 1)
return false; return false;
newdirlen = strlen(ovldir) + strlen(newpath) + strlen(newname) + 2; newdirlen = strlen(ovldir) + strlen(newpath) + strlen(newname) + 2;
newdir = must_realloc(NULL, newdirlen + 1); newdir = must_realloc(NULL, newdirlen + 1);
ret = snprintf(newdir, newdirlen + 1, "%s=%s/%s", ovldir, newpath, ret = strnprintf(newdir, newdirlen + 1, "%s=%s/%s", ovldir, newpath, newname);
newname); if (ret < 0)
if (ret < 0 || ret >= newdirlen + 1)
return false; return false;
if (!conf->unexpanded_config) if (!conf->unexpanded_config)
...@@ -3338,14 +3336,14 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath, ...@@ -3338,14 +3336,14 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
olddirlen = strlen(oldpath) + strlen(oldname) + 1; olddirlen = strlen(oldpath) + strlen(oldname) + 1;
olddir = must_realloc(NULL, olddirlen + 1); olddir = must_realloc(NULL, olddirlen + 1);
ret = snprintf(olddir, olddirlen + 1, "%s/%s", oldpath, oldname); ret = strnprintf(olddir, olddirlen + 1, "%s/%s", oldpath, oldname);
if (ret < 0 || ret >= olddirlen + 1) if (ret < 0)
return false; return false;
newdirlen = strlen(newpath) + strlen(newname) + 1; newdirlen = strlen(newpath) + strlen(newname) + 1;
newdir = must_realloc(NULL, newdirlen + 1); newdir = must_realloc(NULL, newdirlen + 1);
ret = snprintf(newdir, newdirlen + 1, "%s/%s", newpath, newname); ret = strnprintf(newdir, newdirlen + 1, "%s/%s", newpath, newname);
if (ret < 0 || ret >= newdirlen + 1) if (ret < 0)
return false; return false;
if (!conf->unexpanded_config) if (!conf->unexpanded_config)
...@@ -3877,10 +3875,10 @@ static int get_config_idmaps(const char *key, char *retv, int inlen, ...@@ -3877,10 +3875,10 @@ static int get_config_idmaps(const char *key, char *retv, int inlen,
listlen = lxc_list_len(&c->id_map); listlen = lxc_list_len(&c->id_map);
lxc_list_for_each(it, &c->id_map) { lxc_list_for_each(it, &c->id_map) {
struct id_map *map = it->elem; struct id_map *map = it->elem;
ret = snprintf(buf, __LXC_IDMAP_STR_BUF, "%c %lu %lu %lu", ret = strnprintf(buf, sizeof(buf), "%c %lu %lu %lu",
(map->idtype == ID_TYPE_UID) ? 'u' : 'g', (map->idtype == ID_TYPE_UID) ? 'u' : 'g',
map->nsid, map->hostid, map->range); map->nsid, map->hostid, map->range);
if (ret < 0 || ret >= __LXC_IDMAP_STR_BUF) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
strprint(retv, inlen, "%s%s", buf, (listlen-- > 1) ? "\n" : ""); strprint(retv, inlen, "%s%s", buf, (listlen-- > 1) ? "\n" : "");
......
...@@ -768,18 +768,17 @@ bool new_hwaddr(char *hwaddr) ...@@ -768,18 +768,17 @@ bool new_hwaddr(char *hwaddr)
seed = randseed(false); seed = randseed(false);
ret = snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand_r(&seed) % 255, ret = strnprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand_r(&seed) % 255,
rand_r(&seed) % 255, rand_r(&seed) % 255); rand_r(&seed) % 255, rand_r(&seed) % 255);
#else #else
(void)randseed(true); (void)randseed(true);
ret = snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand() % 255, ret = strnprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand() % 255,
rand() % 255, rand() % 255); rand() % 255, rand() % 255);
#endif #endif
if (ret < 0 || ret >= 18) { if (ret < 0)
return log_error_errno(false, EIO, "Failed to call snprintf()"); return log_error_errno(false, EIO, "Failed to call strnprintf()");
}
return true; return true;
} }
......
...@@ -83,8 +83,8 @@ static int load_tty_major_minor(char *directory, char *output, int len) ...@@ -83,8 +83,8 @@ static int load_tty_major_minor(char *directory, char *output, int len)
char path[PATH_MAX]; char path[PATH_MAX];
ssize_t ret; ssize_t ret;
ret = snprintf(path, sizeof(path), "%s/tty.info", directory); ret = strnprintf(path, sizeof(path), "%s/tty.info", directory);
if (ret < 0 || (size_t)ret >= sizeof(path)) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
ret = lxc_read_from_file(path, output, len); ret = lxc_read_from_file(path, output, len);
...@@ -249,8 +249,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -249,8 +249,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
static_args += 2 * lxc_list_len(&opts->c->lxc_conf->mount_list); static_args += 2 * lxc_list_len(&opts->c->lxc_conf->mount_list);
ret = snprintf(log, PATH_MAX, "%s/%s.log", opts->user->directory, opts->action); ret = strnprintf(log, sizeof(log), "%s/%s.log", opts->user->directory, opts->action);
if (ret < 0 || ret >= PATH_MAX) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
args = zalloc(sizeof(struct criu_exec_args) + (static_args * sizeof(char **))); args = zalloc(sizeof(struct criu_exec_args) + (static_args * sizeof(char **)));
...@@ -367,10 +367,10 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -367,10 +367,10 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
continue; continue;
if (strcmp(opts->action, "dump") == 0) if (strcmp(opts->action, "dump") == 0)
ret = snprintf(arg, sizeof(arg), "/%s:%s", mntent.mnt_dir, mntent.mnt_dir); ret = strnprintf(arg, sizeof(arg), "/%s:%s", mntent.mnt_dir, mntent.mnt_dir);
else else
ret = snprintf(arg, sizeof(arg), "%s:%s", mntent.mnt_dir, mntent.mnt_fsname); ret = strnprintf(arg, sizeof(arg), "%s:%s", mntent.mnt_dir, mntent.mnt_fsname);
if (ret < 0 || ret >= sizeof(arg)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create mount entry"); return log_error_errno(-EIO, EIO, "Failed to create mount entry");
DECLARE_ARG("--ext-mount-map"); DECLARE_ARG("--ext-mount-map");
...@@ -386,8 +386,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -386,8 +386,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (init_pid < 0) if (init_pid < 0)
return log_error_errno(-ESRCH, ESRCH, "Failed to retrieve init pid of container"); return log_error_errno(-ESRCH, ESRCH, "Failed to retrieve init pid of container");
ret = snprintf(init_pid_str, sizeof(init_pid_str), "%d", init_pid); ret = strnprintf(init_pid_str, sizeof(init_pid_str), "%d", init_pid);
if (ret < 0 || (size_t)ret >= sizeof(init_pid_str)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create entry for init pid of container"); return log_error_errno(-EIO, EIO, "Failed to create entry for init pid of container");
DECLARE_ARG("-t"); DECLARE_ARG("-t");
...@@ -400,10 +400,10 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -400,10 +400,10 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
return log_error_errno(-ENOENT, ENOENT, "Failed getting freezer path"); return log_error_errno(-ENOENT, ENOENT, "Failed getting freezer path");
if (pure_unified_layout(cgroup_ops)) if (pure_unified_layout(cgroup_ops))
ret = snprintf(log, sizeof(log), "/sys/fs/cgroup/%s", freezer_relative); ret = strnprintf(log, sizeof(log), "/sys/fs/cgroup/%s", freezer_relative);
else else
ret = snprintf(log, sizeof(log), "/sys/fs/cgroup/freezer/%s", freezer_relative); ret = strnprintf(log, sizeof(log), "/sys/fs/cgroup/freezer/%s", freezer_relative);
if (ret < 0 || ret >= sizeof(log)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to freezer cgroup entry"); return log_error_errno(-EIO, EIO, "Failed to freezer cgroup entry");
if (!opts->user->disable_skip_in_flight && if (!opts->user->disable_skip_in_flight &&
...@@ -464,15 +464,15 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -464,15 +464,15 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (opts->console_fd < 0) if (opts->console_fd < 0)
return log_error_errno(-EINVAL, EINVAL, "lxc.console.path configured on source host but not target"); return log_error_errno(-EINVAL, EINVAL, "lxc.console.path configured on source host but not target");
ret = snprintf(buf, sizeof(buf), "fd[%d]:%s", opts->console_fd, ttys); ret = strnprintf(buf, sizeof(buf), "fd[%d]:%s", opts->console_fd, ttys);
if (ret < 0 || ret >= sizeof(buf)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create console entry"); return log_error_errno(-EIO, EIO, "Failed to create console entry");
DECLARE_ARG("--inherit-fd"); DECLARE_ARG("--inherit-fd");
DECLARE_ARG(buf); DECLARE_ARG(buf);
} }
if (opts->console_name) { if (opts->console_name) {
if (snprintf(buf, sizeof(buf), "console:%s", opts->console_name) < 0) if (strnprintf(buf, sizeof(buf), "console:%s", opts->console_name) < 0)
return log_error_errno(-EIO, EIO, "Failed to create console entry"); return log_error_errno(-EIO, EIO, "Failed to create console entry");
DECLARE_ARG("--ext-mount-map"); DECLARE_ARG("--ext-mount-map");
...@@ -482,10 +482,10 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -482,10 +482,10 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (lxc_conf->lsm_aa_profile || lxc_conf->lsm_se_context) { if (lxc_conf->lsm_aa_profile || lxc_conf->lsm_se_context) {
if (lxc_conf->lsm_aa_profile) if (lxc_conf->lsm_aa_profile)
ret = snprintf(buf, sizeof(buf), "apparmor:%s", lxc_conf->lsm_aa_profile); ret = strnprintf(buf, sizeof(buf), "apparmor:%s", lxc_conf->lsm_aa_profile);
else else
ret = snprintf(buf, sizeof(buf), "selinux:%s", lxc_conf->lsm_se_context); ret = strnprintf(buf, sizeof(buf), "selinux:%s", lxc_conf->lsm_se_context);
if (ret < 0 || ret >= sizeof(buf)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create lsm entry"); return log_error_errno(-EIO, EIO, "Failed to create lsm entry");
DECLARE_ARG("--lsm-profile"); DECLARE_ARG("--lsm-profile");
...@@ -513,8 +513,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -513,8 +513,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (retlen >= sizeof(eth)) if (retlen >= sizeof(eth))
return log_error_errno(-E2BIG, E2BIG, "Failed to append veth device name"); return log_error_errno(-E2BIG, E2BIG, "Failed to append veth device name");
} else { } else {
ret = snprintf(eth, sizeof(eth), "eth%d", netnr); ret = strnprintf(eth, sizeof(eth), "eth%d", netnr);
if (ret < 0 || ret >= sizeof(eth)) if (ret < 0)
return log_error_errno(-E2BIG, E2BIG, "Failed to append veth device name"); return log_error_errno(-E2BIG, E2BIG, "Failed to append veth device name");
} }
...@@ -526,16 +526,16 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -526,16 +526,16 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (n->link[0] != '\0') { if (n->link[0] != '\0') {
if (external_not_veth) if (external_not_veth)
ret = snprintf(buf, sizeof(buf), "veth[%s]:%s@%s", eth, veth, n->link); ret = strnprintf(buf, sizeof(buf), "veth[%s]:%s@%s", eth, veth, n->link);
else else
ret = snprintf(buf, sizeof(buf), "%s=%s@%s", eth, veth, n->link); ret = strnprintf(buf, sizeof(buf), "%s=%s@%s", eth, veth, n->link);
} else { } else {
if (external_not_veth) if (external_not_veth)
ret = snprintf(buf, sizeof(buf), "veth[%s]:%s", eth, veth); ret = strnprintf(buf, sizeof(buf), "veth[%s]:%s", eth, veth);
else else
ret = snprintf(buf, sizeof(buf), "%s=%s", eth, veth); ret = strnprintf(buf, sizeof(buf), "%s=%s", eth, veth);
} }
if (ret < 0 || ret >= sizeof(buf)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to append veth device name"); return log_error_errno(-EIO, EIO, "Failed to append veth device name");
TRACE("Added veth device entry %s", buf); TRACE("Added veth device entry %s", buf);
...@@ -544,8 +544,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -544,8 +544,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (n->link[0] == '\0') if (n->link[0] == '\0')
return log_error_errno(-EINVAL, EINVAL, "Failed to find host interface for macvlan %s", n->name); return log_error_errno(-EINVAL, EINVAL, "Failed to find host interface for macvlan %s", n->name);
ret = snprintf(buf, sizeof(buf), "macvlan[%s]:%s", eth, n->link); ret = strnprintf(buf, sizeof(buf), "macvlan[%s]:%s", eth, n->link);
if (ret < 0 || ret >= sizeof(buf)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to add macvlan entry"); return log_error_errno(-EIO, EIO, "Failed to add macvlan entry");
TRACE("Added macvlan device entry %s", buf); TRACE("Added macvlan device entry %s", buf);
...@@ -574,8 +574,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -574,8 +574,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (lxc_log_trace()) { if (lxc_log_trace()) {
buf[0] = 0; buf[0] = 0;
for (int i = 0, pos = 0; i < args->argc && args->argv[i]; i++) { for (int i = 0, pos = 0; i < args->argc && args->argv[i]; i++) {
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s ", args->argv[i]); ret = strnprintf(buf + pos, sizeof(buf) - pos, "%s ", args->argv[i]);
if (ret < 0 || ret >= sizeof(buf) - pos) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to reorder entries"); return log_error_errno(-EIO, EIO, "Failed to reorder entries");
else else
pos += ret; pos += ret;
...@@ -857,8 +857,8 @@ static bool restore_net_info(struct lxc_container *c) ...@@ -857,8 +857,8 @@ static bool restore_net_info(struct lxc_container *c)
if (netdev->type != LXC_NET_VETH) if (netdev->type != LXC_NET_VETH)
continue; continue;
ret = snprintf(template, sizeof(template), "vethXXXXXX"); ret = strnprintf(template, sizeof(template), "vethXXXXXX");
if (ret < 0 || ret >= sizeof(template)) if (ret < 0)
goto out_unlock; goto out_unlock;
if (netdev->priv.veth_attr.pair[0] == '\0' && if (netdev->priv.veth_attr.pair[0] == '\0' &&
...@@ -1052,9 +1052,9 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ ...@@ -1052,9 +1052,9 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
ERROR("criu process exited %d, output:\n%s", WEXITSTATUS(status), buf); ERROR("criu process exited %d, output:\n%s", WEXITSTATUS(status), buf);
goto out_fini_handler; goto out_fini_handler;
} else { } else {
ret = snprintf(buf, sizeof(buf), "/proc/self/task/%lu/children", (unsigned long)syscall(__NR_gettid)); ret = strnprintf(buf, sizeof(buf), "/proc/self/task/%lu/children", (unsigned long)syscall(__NR_gettid));
if (ret < 0 || ret >= sizeof(buf)) { if (ret < 0) {
ERROR("snprintf'd too many characters: %d", ret); ERROR("strnprintf'd too many characters: %d", ret);
goto out_fini_handler; goto out_fini_handler;
} }
...@@ -1097,8 +1097,8 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ ...@@ -1097,8 +1097,8 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
* fail because it's just a beauty thing. We just * fail because it's just a beauty thing. We just
* assign the return here to silence potential. * assign the return here to silence potential.
*/ */
ret = snprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name); ret = strnprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name);
if (ret < 0 || (size_t)ret >= sizeof(title)) if (ret < 0)
INFO("Setting truncated process name"); INFO("Setting truncated process name");
ret = setproctitle(title); ret = setproctitle(title);
...@@ -1149,9 +1149,9 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char * ...@@ -1149,9 +1149,9 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char *
return 0; return 0;
} }
ret = snprintf(path, sizeof(path), "/proc/%d/root/dev/console", c->init_pid(c)); ret = strnprintf(path, sizeof(path), "/proc/%d/root/dev/console", c->init_pid(c));
if (ret < 0 || ret >= sizeof(path)) { if (ret < 0) {
ERROR("snprintf'd too many characters: %d", ret); ERROR("strnprintf'd too many characters: %d", ret);
return -1; return -1;
} }
...@@ -1161,17 +1161,17 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char * ...@@ -1161,17 +1161,17 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char *
return -1; return -1;
} }
ret = snprintf(path, sizeof(path), "%s/tty.info", directory); ret = strnprintf(path, sizeof(path), "%s/tty.info", directory);
if (ret < 0 || ret >= sizeof(path)) { if (ret < 0) {
ERROR("snprintf'd too many characters: %d", ret); ERROR("strnprintf'd too many characters: %d", ret);
return -1; return -1;
} }
ret = snprintf(tty_id, len, "tty[%llx:%llx]", ret = strnprintf(tty_id, len, "tty[%llx:%llx]",
(long long unsigned) sb.st_rdev, (long long unsigned) sb.st_rdev,
(long long unsigned) sb.st_dev); (long long unsigned) sb.st_dev);
if (ret < 0 || ret >= sizeof(path)) { if (ret < 0) {
ERROR("snprintf'd too many characters: %d", ret); ERROR("strnprintf'd too many characters: %d", ret);
return -1; return -1;
} }
...@@ -1313,8 +1313,8 @@ bool __criu_dump(struct lxc_container *c, struct migrate_opts *opts) ...@@ -1313,8 +1313,8 @@ bool __criu_dump(struct lxc_container *c, struct migrate_opts *opts)
char path[PATH_MAX]; char path[PATH_MAX];
int ret; int ret;
ret = snprintf(path, sizeof(path), "%s/inventory.img", opts->directory); ret = strnprintf(path, sizeof(path), "%s/inventory.img", opts->directory);
if (ret < 0 || ret >= sizeof(path)) if (ret < 0)
return false; return false;
if (access(path, F_OK) == 0) { if (access(path, F_OK) == 0) {
......
...@@ -617,8 +617,8 @@ int timens_offset_write(clockid_t clk_id, int64_t s_offset, int64_t ns_offset) ...@@ -617,8 +617,8 @@ int timens_offset_write(clockid_t clk_id, int64_t s_offset, int64_t ns_offset)
if (fd < 0) if (fd < 0)
return -errno; return -errno;
len = snprintf(buf, sizeof(buf), "%d %" PRId64 " %" PRId64, clk_id, s_offset, ns_offset); len = strnprintf(buf, sizeof(buf), "%d %" PRId64 " %" PRId64, clk_id, s_offset, ns_offset);
if (len < 0 || len >= sizeof(buf)) if (len < 0)
return ret_errno(EFBIG); return ret_errno(EFBIG);
ret = lxc_write_nointr(fd, buf, len); ret = lxc_write_nointr(fd, buf, len);
......
...@@ -280,19 +280,19 @@ static int lxc_unix_epoch_to_utc(char *buf, size_t bufsize, const struct timespe ...@@ -280,19 +280,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)); seconds = (time->tv_sec - d_in_s - h_in_s - (minutes * 60));
/* Make string from nanoseconds. */ /* Make string from nanoseconds. */
ret = snprintf(nanosec, sizeof(nanosec), "%"PRId64, (int64_t)time->tv_nsec); ret = strnprintf(nanosec, sizeof(nanosec), "%"PRId64, (int64_t)time->tv_nsec);
if (ret < 0 || (size_t)ret >= sizeof(nanosec)) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
/* /*
* Create final timestamp for the log and shorten nanoseconds to 3 * Create final timestamp for the log and shorten nanoseconds to 3
* digit precision. * digit precision.
*/ */
ret = snprintf(buf, bufsize, ret = strnprintf(buf, bufsize,
"%" PRId64 "%02" PRId64 "%02" PRId64 "%02" PRId64 "%" PRId64 "%02" PRId64 "%02" PRId64 "%02" PRId64
"%02" PRId64 "%02" PRId64 ".%.3s", "%02" PRId64 "%02" PRId64 ".%.3s",
year, month, day, hours, minutes, seconds, nanosec); year, month, day, hours, minutes, seconds, nanosec);
if (ret < 0 || (size_t)ret >= bufsize) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
return 0; return 0;
...@@ -346,6 +346,10 @@ static int log_append_logfile(const struct lxc_log_appender *appender, ...@@ -346,6 +346,10 @@ static int log_append_logfile(const struct lxc_log_appender *appender,
if (ret) if (ret)
return ret; return ret;
/*
* We allow truncation here which is why we use snprintf() directly
* instead of strnprintf().
*/
n = snprintf(buffer, sizeof(buffer), n = snprintf(buffer, sizeof(buffer),
"%s%s%s %s %-8s %s - %s:%s:%d - ", "%s%s%s %s %-8s %s - %s:%s:%d - ",
log_prefix, log_prefix,
...@@ -572,10 +576,10 @@ static char *build_log_path(const char *name, const char *lxcpath) ...@@ -572,10 +576,10 @@ static char *build_log_path(const char *name, const char *lxcpath)
return ret_set_errno(NULL, ENOMEM); return ret_set_errno(NULL, ENOMEM);
if (use_dir) 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 else
ret = snprintf(p, len, "%s/%s.log", lxcpath, name); ret = strnprintf(p, len, "%s/%s.log", lxcpath, name);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return ret_set_errno(NULL, EIO); return ret_set_errno(NULL, EIO);
return move_ptr(p); return move_ptr(p);
......
...@@ -103,17 +103,17 @@ static char *lxclock_name(const char *p, const char *n) ...@@ -103,17 +103,17 @@ static char *lxclock_name(const char *p, const char *n)
if (!dest) if (!dest)
return NULL; return NULL;
ret = snprintf(dest, len, "%s/lxc/lock/%s", rundir, p); ret = strnprintf(dest, len, "%s/lxc/lock/%s", rundir, p);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return ret_set_errno(NULL, EIO); return NULL;
ret = mkdir_p(dest, 0755); ret = mkdir_p(dest, 0755);
if (ret < 0) if (ret < 0)
return NULL; return NULL;
ret = snprintf(dest, len, "%s/lxc/lock/%s/.%s", rundir, p, n); ret = strnprintf(dest, len, "%s/lxc/lock/%s/.%s", rundir, p, n);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return ret_set_errno(NULL, EIO); return NULL;
return move_ptr(dest); return move_ptr(dest);
} }
......
...@@ -50,8 +50,8 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path ...@@ -50,8 +50,8 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
return -1; return -1;
if (do_mkdirp) { if (do_mkdirp) {
ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath); ret = strnprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath);
if (ret < 0 || (size_t)ret >= fifo_path_sz) { if (ret < 0) {
ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath); ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
free(rundir); free(rundir);
return -1; return -1;
...@@ -63,8 +63,8 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path ...@@ -63,8 +63,8 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
return ret; return ret;
} }
} }
ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath); ret = strnprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath);
if (ret < 0 || (size_t)ret >= fifo_path_sz) { if (ret < 0) {
ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath); ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
free(rundir); free(rundir);
return -1; return -1;
...@@ -163,27 +163,23 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) ...@@ -163,27 +163,23 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr)
/* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */ /* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */
len = strlen(lxcpath) + 18; len = strlen(lxcpath) + 18;
path = must_realloc(NULL, len); path = must_realloc(NULL, len);
ret = snprintf(path, len, "lxc/%s/monitor-sock", lxcpath); ret = strnprintf(path, len, "lxc/%s/monitor-sock", lxcpath);
if (ret < 0 || (size_t)ret >= len) { if (ret < 0) {
ERROR("Failed to create name for monitor socket"); ERROR("Failed to create name for monitor socket");
return -1; return -1;
} }
/* Note: snprintf() will \0-terminate addr->sun_path on the 106th byte /* Note: strnprintf() will \0-terminate addr->sun_path on the 106th byte
* and so the abstract socket name has 105 "meaningful" characters. This * and so the abstract socket name has 105 "meaningful" characters. This
* is absolutely intentional. For further info read the comment for this * is absolutely intentional. For further info read the comment for this
* function above! * function above!
*/ */
len = sizeof(addr->sun_path) - 1; len = sizeof(addr->sun_path) - 1;
hash = fnv_64a_buf(path, ret, FNV1A_64_INIT); hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
ret = snprintf(addr->sun_path, len, "@lxc/%016" PRIx64 "/%s", hash, lxcpath); ret = strnprintf(addr->sun_path, len, "@lxc/%016" PRIx64 "/%s", hash, lxcpath);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create hashed name for monitor socket"); ERROR("Failed to create hashed name for monitor socket");
goto on_error; goto on_error;
} else if ((size_t)ret >= len) {
errno = ENAMETOOLONG;
SYSERROR("The name of monitor socket too long (%d bytes)", ret);
goto on_error;
} }
/* replace @ with \0 */ /* replace @ with \0 */
...@@ -353,8 +349,8 @@ int lxc_monitord_spawn(const char *lxcpath) ...@@ -353,8 +349,8 @@ int lxc_monitord_spawn(const char *lxcpath)
close(pipefd[0]); close(pipefd[0]);
ret = snprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]); ret = strnprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]);
if (ret < 0 || ret >= sizeof(pipefd_str)) { if (ret < 0) {
ERROR("Failed to create pid argument to pass to monitord"); ERROR("Failed to create pid argument to pass to monitord");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
......
...@@ -138,8 +138,8 @@ static int __fs_prepare(const char *fs_name, int fd_from) ...@@ -138,8 +138,8 @@ static int __fs_prepare(const char *fs_name, int fd_from)
* only use fds for mount. * only use fds for mount.
*/ */
if (fd_from >= 0) { if (fd_from >= 0) {
ret = snprintf(source, sizeof(source), "/proc/self/fd/%d", fd_from); ret = strnprintf(source, sizeof(source), "/proc/self/fd/%d", fd_from);
if (ret < 0 || ret >= sizeof(source)) if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create /proc/self/fd/%d", fd_from); return log_error_errno(-EIO, EIO, "Failed to create /proc/self/fd/%d", fd_from);
} }
......
...@@ -231,10 +231,10 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family) ...@@ -231,10 +231,10 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
if (family != AF_INET && family != AF_INET6) if (family != AF_INET && family != AF_INET6)
return ret_set_errno(-1, EINVAL); return ret_set_errno(-1, EINVAL);
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s", ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname, family == AF_INET ? "ipv4" : "ipv6", ifname,
"forwarding"); "forwarding");
if (ret < 0 || (size_t)ret >= sizeof(path)) if (ret < 0)
return ret_set_errno(-1, E2BIG); return ret_set_errno(-1, E2BIG);
return lxc_read_file_expect(path, buf, 1, "1"); return lxc_read_file_expect(path, buf, 1, "1");
...@@ -359,8 +359,8 @@ static int setup_veth_native_bridge_vlan(char *veth1, struct lxc_netdev *netdev) ...@@ -359,8 +359,8 @@ static int setup_veth_native_bridge_vlan(char *veth1, struct lxc_netdev *netdev)
return 0; return 0;
/* Check vlan filtering is enabled on parent bridge. */ /* Check vlan filtering is enabled on parent bridge. */
rc = snprintf(path, sizeof(path), "/sys/class/net/%s/bridge/vlan_filtering", netdev->link); rc = strnprintf(path, sizeof(path), "/sys/class/net/%s/bridge/vlan_filtering", netdev->link);
if (rc < 0 || (size_t)rc >= sizeof(path)) if (rc < 0)
return -1; return -1;
rc = lxc_read_from_file(path, buf, sizeof(buf)); rc = lxc_read_from_file(path, buf, sizeof(buf));
...@@ -382,8 +382,8 @@ static int setup_veth_native_bridge_vlan(char *veth1, struct lxc_netdev *netdev) ...@@ -382,8 +382,8 @@ static int setup_veth_native_bridge_vlan(char *veth1, struct lxc_netdev *netdev)
unsigned short default_pvid; unsigned short default_pvid;
/* Get the bridge's default VLAN PVID. */ /* Get the bridge's default VLAN PVID. */
rc = snprintf(path, sizeof(path), "/sys/class/net/%s/bridge/default_pvid", netdev->link); rc = strnprintf(path, sizeof(path), "/sys/class/net/%s/bridge/default_pvid", netdev->link);
if (rc < 0 || (size_t)rc >= sizeof(path)) if (rc < 0)
return -1; return -1;
rc = lxc_read_from_file(path, buf, sizeof(buf)); rc = lxc_read_from_file(path, buf, sizeof(buf));
...@@ -443,8 +443,8 @@ static int lxc_ovs_setup_bridge_vlan_exec(void *data) ...@@ -443,8 +443,8 @@ static int lxc_ovs_setup_bridge_vlan_exec(void *data)
char buf[5]; char buf[5];
int rc; int rc;
rc = snprintf(buf, sizeof(buf), "%u", args->vlan_id); rc = strnprintf(buf, sizeof(buf), "%u", args->vlan_id);
if (rc < 0 || (size_t)rc >= sizeof(buf)) if (rc < 0)
return log_error_errno(-1, EINVAL, "Failed to parse ovs bridge vlan \"%d\"", args->vlan_id); return log_error_errno(-1, EINVAL, "Failed to parse ovs bridge vlan \"%d\"", args->vlan_id);
tag = must_concat(NULL, "tag=", buf, (char *)NULL); tag = must_concat(NULL, "tag=", buf, (char *)NULL);
...@@ -509,8 +509,8 @@ static int setup_veth_ovs_bridge_vlan(char *veth1, struct lxc_netdev *netdev) ...@@ -509,8 +509,8 @@ static int setup_veth_ovs_bridge_vlan(char *veth1, struct lxc_netdev *netdev)
char buf[5]; /* Sufficient size to fit max VLAN ID (4094) null char. */ char buf[5]; /* Sufficient size to fit max VLAN ID (4094) null char. */
int rc; int rc;
rc = snprintf(buf, sizeof(buf), "%u", vlan_id); rc = strnprintf(buf, sizeof(buf), "%u", vlan_id);
if (rc < 0 || (size_t)rc >= sizeof(buf)) { if (rc < 0) {
free_ovs_veth_vlan_args(&args); free_ovs_veth_vlan_args(&args);
return log_error_errno(-1, EINVAL, "Failed to parse tagged vlan \"%u\" for interface \"%s\"", vlan_id, veth1); return log_error_errno(-1, EINVAL, "Failed to parse tagged vlan \"%u\" for interface \"%s\"", vlan_id, veth1);
} }
...@@ -553,8 +553,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd ...@@ -553,8 +553,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
if (handler->conf->reboot) if (handler->conf->reboot)
lxc_netdev_delete_by_name(veth1); lxc_netdev_delete_by_name(veth1);
} else { } else {
err = snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX"); err = strnprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX");
if (err < 0 || (size_t)err >= sizeof(veth1buf)) if (err < 0)
return -1; return -1;
veth1 = lxc_ifname_alnum_case_sensitive(veth1buf); veth1 = lxc_ifname_alnum_case_sensitive(veth1buf);
...@@ -565,8 +565,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd ...@@ -565,8 +565,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ); memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ);
} }
err = snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX"); err = strnprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
if (err < 0 || (size_t)err >= sizeof(veth2buf)) if (err < 0)
return -1; return -1;
veth2 = lxc_ifname_alnum_case_sensitive(veth2buf); veth2 = lxc_ifname_alnum_case_sensitive(veth2buf);
...@@ -781,8 +781,8 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n ...@@ -781,8 +781,8 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
return -1; return -1;
} }
err = snprintf(peer, sizeof(peer), "mcXXXXXX"); err = strnprintf(peer, sizeof(peer), "mcXXXXXX");
if (err < 0 || (size_t)err >= sizeof(peer)) if (err < 0)
return -1; return -1;
if (!lxc_ifname_alnum_case_sensitive(peer)) if (!lxc_ifname_alnum_case_sensitive(peer))
...@@ -931,8 +931,8 @@ static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *ne ...@@ -931,8 +931,8 @@ static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *ne
return -1; return -1;
} }
err = snprintf(peer, sizeof(peer), "ipXXXXXX"); err = strnprintf(peer, sizeof(peer), "ipXXXXXX");
if (err < 0 || (size_t)err >= sizeof(peer)) if (err < 0)
return -1; return -1;
if (!lxc_ifname_alnum_case_sensitive(peer)) if (!lxc_ifname_alnum_case_sensitive(peer))
...@@ -1006,9 +1006,9 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd ...@@ -1006,9 +1006,9 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
return -1; return -1;
} }
err = snprintf(peer, sizeof(peer), "vlan%d-%d", err = strnprintf(peer, sizeof(peer), "vlan%d-%d",
netdev->priv.vlan_attr.vid, vlan_cntr++); netdev->priv.vlan_attr.vid, vlan_cntr++);
if (err < 0 || (size_t)err >= sizeof(peer)) if (err < 0)
return -1; return -1;
err = lxc_vlan_create(netdev->link, peer, netdev->priv.vlan_attr.vid); err = lxc_vlan_create(netdev->link, peer, netdev->priv.vlan_attr.vid);
...@@ -1489,8 +1489,8 @@ char *is_wlan(const char *ifname) ...@@ -1489,8 +1489,8 @@ char *is_wlan(const char *ifname)
len = strlen(ifname) + strlen(PHYSNAME) - 1; len = strlen(ifname) + strlen(PHYSNAME) - 1;
path = must_realloc(NULL, len + 1); path = must_realloc(NULL, len + 1);
ret = snprintf(path, len, PHYSNAME, ifname); ret = strnprintf(path, len, PHYSNAME, ifname);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return NULL; return NULL;
f = fopen(path, "re"); f = fopen(path, "re");
...@@ -2217,9 +2217,10 @@ static int ip_forwarding_set(const char *ifname, int family, int flag) ...@@ -2217,9 +2217,10 @@ static int ip_forwarding_set(const char *ifname, int family, int flag)
if (family != AF_INET && family != AF_INET6) if (family != AF_INET && family != AF_INET6)
return -EINVAL; return -EINVAL;
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s", ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname, "forwarding"); family == AF_INET ? "ipv4" : "ipv6", ifname,
if (ret < 0 || (size_t)ret >= sizeof(path)) "forwarding");
if (ret < 0)
return -E2BIG; return -E2BIG;
return proc_sys_net_write(path, flag ? "1" : "0"); return proc_sys_net_write(path, flag ? "1" : "0");
...@@ -2243,10 +2244,10 @@ static int neigh_proxy_set(const char *ifname, int family, int flag) ...@@ -2243,10 +2244,10 @@ static int neigh_proxy_set(const char *ifname, int family, int flag)
if (family != AF_INET && family != AF_INET6) if (family != AF_INET && family != AF_INET6)
return -EINVAL; return -EINVAL;
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s", ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname, family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp"); family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0 || (size_t)ret >= sizeof(path)) if (ret < 0)
return -E2BIG; return -E2BIG;
return proc_sys_net_write(path, flag ? "1" : "0"); return proc_sys_net_write(path, flag ? "1" : "0");
...@@ -2261,10 +2262,10 @@ static int lxc_is_ip_neigh_proxy_enabled(const char *ifname, int family) ...@@ -2261,10 +2262,10 @@ static int lxc_is_ip_neigh_proxy_enabled(const char *ifname, int family)
if (family != AF_INET && family != AF_INET6) if (family != AF_INET && family != AF_INET6)
return ret_set_errno(-1, EINVAL); return ret_set_errno(-1, EINVAL);
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s", ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname, family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp"); family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0 || (size_t)ret >= sizeof(path)) if (ret < 0)
return ret_set_errno(-1, E2BIG); return ret_set_errno(-1, E2BIG);
return lxc_read_file_expect(path, buf, 1, "1"); return lxc_read_file_expect(path, buf, 1, "1");
...@@ -2629,9 +2630,9 @@ bool is_ovs_bridge(const char *bridge) ...@@ -2629,9 +2630,9 @@ bool is_ovs_bridge(const char *bridge)
struct stat sb; struct stat sb;
char brdirname[22 + IFNAMSIZ + 1] = {0}; char brdirname[22 + IFNAMSIZ + 1] = {0};
ret = snprintf(brdirname, 22 + IFNAMSIZ + 1, "/sys/class/net/%s/bridge", ret = strnprintf(brdirname, 22 + IFNAMSIZ + 1,
bridge); "/sys/class/net/%s/bridge", bridge);
if (ret < 0 || (size_t)ret >= 22 + IFNAMSIZ + 1) if (ret < 0)
return false; return false;
ret = stat(brdirname, &sb); ret = stat(brdirname, &sb);
...@@ -2795,28 +2796,24 @@ char *lxc_ifname_alnum_case_sensitive(char *template) ...@@ -2795,28 +2796,24 @@ char *lxc_ifname_alnum_case_sensitive(char *template)
int setup_private_host_hw_addr(char *veth1) int setup_private_host_hw_addr(char *veth1)
{ {
int err, sockfd; __do_close int sockfd = -EBADF;
int err;
struct ifreq ifr; struct ifreq ifr;
sockfd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); sockfd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sockfd < 0) if (sockfd < 0)
return -errno; return -errno;
err = snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1); err = strnprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
if (err < 0 || (size_t)err >= IFNAMSIZ) { if (err < 0)
close(sockfd); return err;
return -E2BIG;
}
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr); err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) { if (err < 0)
close(sockfd);
return -errno; return -errno;
}
ifr.ifr_hwaddr.sa_data[0] = 0xfe; ifr.ifr_hwaddr.sa_data[0] = 0xfe;
err = ioctl(sockfd, SIOCSIFHWADDR, &ifr); err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
close(sockfd);
if (err < 0) if (err < 0)
return -errno; return -errno;
...@@ -2910,8 +2907,8 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -2910,8 +2907,8 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
ret = snprintf(pidstr, sizeof(pidstr), "%d", pid); ret = strnprintf(pidstr, sizeof(pidstr), "%d", pid);
if (ret < 0 || ret >= sizeof(pidstr)) if (ret < 0)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
pidstr[sizeof(pidstr) - 1] = '\0'; pidstr[sizeof(pidstr) - 1] = '\0';
...@@ -3108,9 +3105,9 @@ static bool lxc_delete_network_unpriv(struct lxc_handler *handler) ...@@ -3108,9 +3105,9 @@ static bool lxc_delete_network_unpriv(struct lxc_handler *handler)
if (handler->nsfd[LXC_NS_NET] < 0) if (handler->nsfd[LXC_NS_NET] < 0)
return log_debug(false, "Cannot not guarantee safe deletion of network devices. Manual cleanup maybe needed"); return log_debug(false, "Cannot not guarantee safe deletion of network devices. Manual cleanup maybe needed");
ret = snprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d", ret = strnprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d",
lxc_raw_getpid(), handler->nsfd[LXC_NS_NET]); lxc_raw_getpid(), handler->nsfd[LXC_NS_NET]);
if (ret < 0 || ret >= sizeof(netns_path)) if (ret < 0)
return false; return false;
lxc_list_for_each(iterator, network) { lxc_list_for_each(iterator, network) {
......
...@@ -98,9 +98,9 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name) ...@@ -98,9 +98,9 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
if (memfd < 0) { if (memfd < 0) {
char template[PATH_MAX]; char template[PATH_MAX];
ret = snprintf(template, sizeof(template), ret = strnprintf(template, sizeof(template),
P_tmpdir "/.%s_XXXXXX", memfd_name); P_tmpdir "/.%s_XXXXXX", memfd_name);
if (ret < 0 || (size_t)ret >= sizeof(template)) if (ret < 0)
return; return;
tmpfd = lxc_make_tmpfile(template, true); tmpfd = lxc_make_tmpfile(template, true);
...@@ -151,8 +151,8 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name) ...@@ -151,8 +151,8 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
} else { } else {
char procfd[LXC_PROC_PID_FD_LEN]; char procfd[LXC_PROC_PID_FD_LEN];
ret = snprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", tmpfd); ret = strnprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", tmpfd);
if (ret < 0 || (size_t)ret >= sizeof(procfd)) if (ret < 0)
return; return;
execfd = open(procfd, O_PATH | O_CLOEXEC); execfd = open(procfd, O_PATH | O_CLOEXEC);
......
...@@ -1418,7 +1418,13 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data, ...@@ -1418,7 +1418,13 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
resp->id = req_id = req->id; resp->id = req_id = req->id;
TRACE("Received seccomp notification with id(%llu)", (long long unsigned int)req_id); TRACE("Received seccomp notification with id(%llu)", (long long unsigned int)req_id);
snprintf(mem_path, sizeof(mem_path), "/proc/%d", req->pid); ret = strnprintf(mem_path, sizeof(mem_path), "/proc/%d", req->pid);
if (ret < 0) {
seccomp_notify_default_answer(fd, req, resp, hdlr);
SYSERROR("Failed to create path to process's proc directory");
goto out;
}
fd_pid = open(mem_path, O_RDONLY | O_DIRECTORY | O_CLOEXEC); fd_pid = open(mem_path, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
if (fd_pid < 0) { if (fd_pid < 0) {
seccomp_notify_default_answer(fd, req, resp, hdlr); seccomp_notify_default_answer(fd, req, resp, hdlr);
...@@ -1426,7 +1432,13 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data, ...@@ -1426,7 +1432,13 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
goto out; goto out;
} }
snprintf(mem_path, sizeof(mem_path), "/proc/%d/mem", req->pid); ret = strnprintf(mem_path, sizeof(mem_path), "/proc/%d/mem", req->pid);
if (ret < 0) {
seccomp_notify_default_answer(fd, req, resp, hdlr);
SYSERROR("Failed to create path to process's virtual memory");
goto out;
}
fd_mem = open(mem_path, O_RDWR | O_CLOEXEC); fd_mem = open(mem_path, O_RDWR | O_CLOEXEC);
if (fd_mem < 0) { if (fd_mem < 0) {
seccomp_notify_default_answer(fd, req, resp, hdlr); seccomp_notify_default_answer(fd, req, resp, hdlr);
......
...@@ -183,8 +183,8 @@ static bool match_dlog_fds(struct dirent *direntp) ...@@ -183,8 +183,8 @@ static bool match_dlog_fds(struct dirent *direntp)
ssize_t linklen; ssize_t linklen;
int ret; int ret;
ret = snprintf(path, PATH_MAX, "/proc/self/fd/%s", direntp->d_name); ret = strnprintf(path, sizeof(path), "/proc/self/fd/%s", direntp->d_name);
if (ret < 0 || ret >= PATH_MAX) if (ret < 0)
return log_error(false, "Failed to create file descriptor name"); return log_error(false, "Failed to create file descriptor name");
linklen = readlink(path, link, PATH_MAX); linklen = readlink(path, link, PATH_MAX);
...@@ -1147,9 +1147,9 @@ static int do_start(void *data) ...@@ -1147,9 +1147,9 @@ static int do_start(void *data)
if (handler->daemonize && !handler->conf->autodev) { if (handler->daemonize && !handler->conf->autodev) {
char path[PATH_MAX]; char path[PATH_MAX];
ret = snprintf(path, sizeof(path), "%s/dev/null", ret = strnprintf(path, sizeof(path), "%s/dev/null",
handler->conf->rootfs.mount); handler->conf->rootfs.mount);
if (ret < 0 || ret >= sizeof(path)) if (ret < 0)
goto out_warn_father; goto out_warn_father;
ret = access(path, F_OK); ret = access(path, F_OK);
...@@ -1749,8 +1749,8 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1749,8 +1749,8 @@ static int lxc_spawn(struct lxc_handler *handler)
if (!lxc_can_use_pidfd(handler->pidfd)) if (!lxc_can_use_pidfd(handler->pidfd))
close_prot_errno_disarm(handler->pidfd); close_prot_errno_disarm(handler->pidfd);
ret = snprintf(pidstr, 20, "%d", handler->pid); ret = strnprintf(pidstr, 20, "%d", handler->pid);
if (ret < 0 || ret >= 20) if (ret < 0)
goto out_delete_net; goto out_delete_net;
ret = setenv("LXC_PID", pidstr, 1); ret = setenv("LXC_PID", pidstr, 1);
...@@ -2200,8 +2200,8 @@ static void lxc_destroy_container_on_signal(struct lxc_handler *handler, ...@@ -2200,8 +2200,8 @@ static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
} }
INFO("Destroyed rootfs for container \"%s\"", name); INFO("Destroyed rootfs for container \"%s\"", name);
ret = snprintf(destroy, PATH_MAX, "%s/%s", handler->lxcpath, name); ret = strnprintf(destroy, sizeof(destroy), "%s/%s", handler->lxcpath, name);
if (ret < 0 || ret >= PATH_MAX) { if (ret < 0) {
ERROR("Error destroying directory for container \"%s\"", name); ERROR("Error destroying directory for container \"%s\"", name);
return; return;
} }
......
...@@ -276,9 +276,9 @@ char *lxc_deslashify(const char *path) ...@@ -276,9 +276,9 @@ char *lxc_deslashify(const char *path)
char *lxc_append_paths(const char *first, const char *second) char *lxc_append_paths(const char *first, const char *second)
{ {
__do_free char *result = NULL;
int ret; int ret;
size_t len; size_t len;
char *result = NULL;
int pattern_type = 0; int pattern_type = 0;
len = strlen(first) + strlen(second) + 1; len = strlen(first) + strlen(second) + 1;
...@@ -287,20 +287,18 @@ char *lxc_append_paths(const char *first, const char *second) ...@@ -287,20 +287,18 @@ char *lxc_append_paths(const char *first, const char *second)
pattern_type = 1; pattern_type = 1;
} }
result = calloc(1, len); result = zalloc(len);
if (!result) if (!result)
return NULL; return NULL;
if (pattern_type == 0) if (pattern_type == 0)
ret = snprintf(result, len, "%s%s", first, second); ret = strnprintf(result, len, "%s%s", first, second);
else else
ret = snprintf(result, len, "%s/%s", first, second); ret = strnprintf(result, len, "%s/%s", first, second);
if (ret < 0 || (size_t)ret >= len) { if (ret < 0)
free(result);
return NULL; return NULL;
}
return result; return move_ptr(result);
} }
bool lxc_string_in_list(const char *needle, const char *haystack, char _sep) bool lxc_string_in_list(const char *needle, const char *haystack, char _sep)
......
...@@ -140,4 +140,13 @@ static inline bool strequal(const char *str, const char *eq) ...@@ -140,4 +140,13 @@ static inline bool strequal(const char *str, const char *eq)
return strcmp(str, eq) == 0; return strcmp(str, eq) == 0;
} }
#define strnprintf(buf, buf_size, ...) \
({ \
int __ret_strnprintf; \
__ret_strnprintf = snprintf(buf, buf_size, ##__VA_ARGS__); \
if (__ret_strnprintf < 0 || (size_t)__ret_strnprintf >= buf_size) \
__ret_strnprintf = ret_errno(EIO); \
__ret_strnprintf; \
})
#endif /* __LXC_STRING_UTILS_H */ #endif /* __LXC_STRING_UTILS_H */
...@@ -209,8 +209,8 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) ...@@ -209,8 +209,8 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
len = strlen(terminal->log_path) + sizeof(".1"); len = strlen(terminal->log_path) + sizeof(".1");
tmp = must_realloc(NULL, len); tmp = must_realloc(NULL, len);
ret = snprintf(tmp, len, "%s.1", terminal->log_path); ret = strnprintf(tmp, len, "%s.1", terminal->log_path);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return -EFBIG; return -EFBIG;
close(terminal->log_fd); close(terminal->log_fd);
......
...@@ -84,8 +84,8 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, ...@@ -84,8 +84,8 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev,
!strcmp(direntp->d_name, "..")) !strcmp(direntp->d_name, ".."))
continue; continue;
rc = snprintf(pathname, PATH_MAX, "%s/%s", dirname, direntp->d_name); rc = strnprintf(pathname, sizeof(pathname), "%s/%s", dirname, direntp->d_name);
if (rc < 0 || rc >= PATH_MAX) { if (rc < 0) {
ERROR("The name of path is too long"); ERROR("The name of path is too long");
failed = 1; failed = 1;
continue; continue;
...@@ -267,8 +267,8 @@ char *get_rundir(void) ...@@ -267,8 +267,8 @@ char *get_rundir(void)
if (!rundir) if (!rundir)
return NULL; return NULL;
ret = snprintf(rundir, len, "%s/.cache/lxc/run/", homedir); ret = strnprintf(rundir, len, "%s/.cache/lxc/run/", homedir);
if (ret < 0 || (size_t)ret >= len) if (ret < 0)
return ret_set_errno(NULL, EIO); return ret_set_errno(NULL, EIO);
return move_ptr(rundir); return move_ptr(rundir);
...@@ -660,8 +660,8 @@ bool switch_to_ns(pid_t pid, const char *ns) ...@@ -660,8 +660,8 @@ bool switch_to_ns(pid_t pid, const char *ns)
+ LXC_NAMESPACE_NAME_MAX]; + LXC_NAMESPACE_NAME_MAX];
/* Switch to new ns */ /* Switch to new ns */
ret = snprintf(nspath, sizeof(nspath), "/proc/%d/ns/%s", pid, ns); ret = strnprintf(nspath, sizeof(nspath), "/proc/%d/ns/%s", pid, ns);
if (ret < 0 || ret >= sizeof(nspath)) if (ret < 0)
return false; return false;
fd = open(nspath, O_RDONLY | O_CLOEXEC); fd = open(nspath, O_RDONLY | O_CLOEXEC);
...@@ -734,11 +734,10 @@ char *on_path(const char *cmd, const char *rootfs) ...@@ -734,11 +734,10 @@ char *on_path(const char *cmd, const char *rootfs)
lxc_iterate_parts(entry, path, ":") { lxc_iterate_parts(entry, path, ":") {
if (rootfs) if (rootfs)
ret = snprintf(cmdpath, PATH_MAX, "%s/%s/%s", rootfs, ret = strnprintf(cmdpath, sizeof(cmdpath), "%s/%s/%s", rootfs, entry, cmd);
entry, cmd);
else else
ret = snprintf(cmdpath, PATH_MAX, "%s/%s", entry, cmd); ret = strnprintf(cmdpath, sizeof(cmdpath), "%s/%s", entry, cmd);
if (ret < 0 || ret >= PATH_MAX) if (ret < 0)
continue; continue;
if (access(cmdpath, X_OK) == 0) if (access(cmdpath, X_OK) == 0)
...@@ -788,8 +787,8 @@ char *choose_init(const char *rootfs) ...@@ -788,8 +787,8 @@ char *choose_init(const char *rootfs)
else else
tmp = empty; tmp = empty;
ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, SBINDIR, "/init.lxc"); ret = strnprintf(retv, PATH_MAX, "%s/%s/%s", tmp, SBINDIR, "/init.lxc");
if (ret < 0 || ret >= PATH_MAX) { if (ret < 0) {
ERROR("The name of path is too long"); ERROR("The name of path is too long");
goto out1; goto out1;
} }
...@@ -797,8 +796,8 @@ char *choose_init(const char *rootfs) ...@@ -797,8 +796,8 @@ char *choose_init(const char *rootfs)
if (access(retv, X_OK) == 0) if (access(retv, X_OK) == 0)
return retv; return retv;
ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, LXCINITDIR, "/lxc/lxc-init"); ret = strnprintf(retv, PATH_MAX, "%s/%s/%s", tmp, LXCINITDIR, "/lxc/lxc-init");
if (ret < 0 || ret >= PATH_MAX) { if (ret < 0) {
ERROR("The name of path is too long"); ERROR("The name of path is too long");
goto out1; goto out1;
} }
...@@ -806,8 +805,8 @@ char *choose_init(const char *rootfs) ...@@ -806,8 +805,8 @@ char *choose_init(const char *rootfs)
if (access(retv, X_OK) == 0) if (access(retv, X_OK) == 0)
return retv; return retv;
ret = snprintf(retv, PATH_MAX, "%s/usr/lib/lxc/lxc-init", tmp); ret = strnprintf(retv, PATH_MAX, "%s/usr/lib/lxc/lxc-init", tmp);
if (ret < 0 || ret >= PATH_MAX) { if (ret < 0) {
ERROR("The name of path is too long"); ERROR("The name of path is too long");
goto out1; goto out1;
} }
...@@ -815,8 +814,8 @@ char *choose_init(const char *rootfs) ...@@ -815,8 +814,8 @@ char *choose_init(const char *rootfs)
if (access(retv, X_OK) == 0) if (access(retv, X_OK) == 0)
return retv; return retv;
ret = snprintf(retv, PATH_MAX, "%s/sbin/lxc-init", tmp); ret = strnprintf(retv, PATH_MAX, "%s/sbin/lxc-init", tmp);
if (ret < 0 || ret >= PATH_MAX) { if (ret < 0) {
ERROR("The name of path is too long"); ERROR("The name of path is too long");
goto out1; goto out1;
} }
...@@ -834,8 +833,8 @@ char *choose_init(const char *rootfs) ...@@ -834,8 +833,8 @@ char *choose_init(const char *rootfs)
if (rootfs) if (rootfs)
goto out1; goto out1;
ret = snprintf(retv, PATH_MAX, "/init.lxc.static"); ret = strnprintf(retv, PATH_MAX, "/init.lxc.static");
if (ret < 0 || ret >= PATH_MAX) { if (ret < 0) {
WARN("Nonsense - name /lxc.init.static too long"); WARN("Nonsense - name /lxc.init.static too long");
goto out1; goto out1;
} }
...@@ -874,8 +873,8 @@ char *get_template_path(const char *t) ...@@ -874,8 +873,8 @@ char *get_template_path(const char *t)
if (!tpath) if (!tpath)
return NULL; return NULL;
ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t); ret = strnprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
if (ret < 0 || ret >= len) { if (ret < 0) {
free(tpath); free(tpath);
return NULL; return NULL;
} }
...@@ -1094,8 +1093,8 @@ int __safe_mount_beneath_at(int beneath_fd, const char *src, const char *dst, co ...@@ -1094,8 +1093,8 @@ int __safe_mount_beneath_at(int beneath_fd, const char *src, const char *dst, co
source_fd = openat2(beneath_fd, src, &how, sizeof(how)); source_fd = openat2(beneath_fd, src, &how, sizeof(how));
if (source_fd < 0) if (source_fd < 0)
return -errno; return -errno;
ret = snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd); ret = strnprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd);
if (ret < 0 || ret >= sizeof(src_buf)) if (ret < 0)
return -EIO; return -EIO;
} else { } else {
src_buf[0] = '\0'; src_buf[0] = '\0';
...@@ -1104,8 +1103,8 @@ int __safe_mount_beneath_at(int beneath_fd, const char *src, const char *dst, co ...@@ -1104,8 +1103,8 @@ int __safe_mount_beneath_at(int beneath_fd, const char *src, const char *dst, co
target_fd = openat2(beneath_fd, dst, &how, sizeof(how)); target_fd = openat2(beneath_fd, dst, &how, sizeof(how));
if (target_fd < 0) if (target_fd < 0)
return log_error_errno(-errno, errno, "Failed to open %d(%s)", beneath_fd, dst); return log_error_errno(-errno, errno, "Failed to open %d(%s)", beneath_fd, dst);
ret = snprintf(tgt_buf, sizeof(tgt_buf), "/proc/self/fd/%d", target_fd); ret = strnprintf(tgt_buf, sizeof(tgt_buf), "/proc/self/fd/%d", target_fd);
if (ret < 0 || ret >= sizeof(tgt_buf)) if (ret < 0)
return -EIO; return -EIO;
if (!is_empty_string(src_buf)) if (!is_empty_string(src_buf))
...@@ -1163,8 +1162,8 @@ int safe_mount(const char *src, const char *dest, const char *fstype, ...@@ -1163,8 +1162,8 @@ int safe_mount(const char *src, const char *dest, const char *fstype,
if (srcfd < 0) if (srcfd < 0)
return srcfd; return srcfd;
ret = snprintf(srcbuf, sizeof(srcbuf), "/proc/self/fd/%d", srcfd); ret = strnprintf(srcbuf, sizeof(srcbuf), "/proc/self/fd/%d", srcfd);
if (ret < 0 || ret >= (int)sizeof(srcbuf)) { if (ret < 0) {
close(srcfd); close(srcfd);
ERROR("Out of memory"); ERROR("Out of memory");
return -EINVAL; return -EINVAL;
...@@ -1183,8 +1182,8 @@ int safe_mount(const char *src, const char *dest, const char *fstype, ...@@ -1183,8 +1182,8 @@ int safe_mount(const char *src, const char *dest, const char *fstype,
return destfd; return destfd;
} }
ret = snprintf(destbuf, sizeof(destbuf), "/proc/self/fd/%d", destfd); ret = strnprintf(destbuf, sizeof(destbuf), "/proc/self/fd/%d", destfd);
if (ret < 0 || ret >= (int)sizeof(destbuf)) { if (ret < 0) {
if (srcfd != -1) if (srcfd != -1)
close(srcfd); close(srcfd);
...@@ -1266,8 +1265,8 @@ bool task_blocks_signal(pid_t pid, int signal) ...@@ -1266,8 +1265,8 @@ bool task_blocks_signal(pid_t pid, int signal)
size_t n = 0; size_t n = 0;
bool bret = false; bool bret = false;
ret = snprintf(status, __PROC_STATUS_LEN, "/proc/%d/status", pid); ret = strnprintf(status, sizeof(status), "/proc/%d/status", pid);
if (ret < 0 || ret >= __PROC_STATUS_LEN) if (ret < 0)
return bret; return bret;
f = fopen(status, "re"); f = fopen(status, "re");
...@@ -1305,10 +1304,10 @@ int lxc_preserve_ns(const int pid, const char *ns) ...@@ -1305,10 +1304,10 @@ int lxc_preserve_ns(const int pid, const char *ns)
* are supported by the kernel by passing in the NULL or the empty * are supported by the kernel by passing in the NULL or the empty
* string. * string.
*/ */
ret = snprintf(path, __NS_PATH_LEN, "/proc/%d/ns%s%s", pid, ret = strnprintf(path, sizeof(path), "/proc/%d/ns%s%s", pid,
!ns || strcmp(ns, "") == 0 ? "" : "/", !ns || strcmp(ns, "") == 0 ? "" : "/",
!ns || strcmp(ns, "") == 0 ? "" : ns); !ns || strcmp(ns, "") == 0 ? "" : ns);
if (ret < 0 || (size_t)ret >= __NS_PATH_LEN) if (ret < 0)
return ret_errno(EIO); return ret_errno(EIO);
return open(path, O_RDONLY | O_CLOEXEC); return open(path, O_RDONLY | O_CLOEXEC);
...@@ -1404,8 +1403,8 @@ static int lxc_get_unused_loop_dev_legacy(char *loop_name) ...@@ -1404,8 +1403,8 @@ static int lxc_get_unused_loop_dev_legacy(char *loop_name)
} }
} }
ret = snprintf(loop_name, LO_NAME_SIZE, "/dev/%s", dp->d_name); ret = strnprintf(loop_name, LO_NAME_SIZE, "/dev/%s", dp->d_name);
if (ret < 0 || ret >= LO_NAME_SIZE) { if (ret < 0) {
close(fd); close(fd);
fd = -1; fd = -1;
continue; continue;
...@@ -1439,15 +1438,15 @@ static int lxc_get_unused_loop_dev(char *name_loop) ...@@ -1439,15 +1438,15 @@ static int lxc_get_unused_loop_dev(char *name_loop)
goto on_error; goto on_error;
} }
ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr); ret = strnprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr);
if (ret < 0 || ret >= LO_NAME_SIZE) if (ret < 0)
goto on_error; goto on_error;
fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC); fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC);
if (fd_tmp < 0) { if (fd_tmp < 0) {
/* on Android loop devices are moved under /dev/block, give it a shot */ /* on Android loop devices are moved under /dev/block, give it a shot */
ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/block/loop%d", loop_nr); ret = strnprintf(name_loop, LO_NAME_SIZE, "/dev/block/loop%d", loop_nr);
if (ret < 0 || ret >= LO_NAME_SIZE) if (ret < 0)
goto on_error; goto on_error;
fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC); fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC);
...@@ -1633,8 +1632,8 @@ bool lxc_nic_exists(char *nic) ...@@ -1633,8 +1632,8 @@ bool lxc_nic_exists(char *nic)
if (!strcmp(nic, "none")) if (!strcmp(nic, "none"))
return true; return true;
ret = snprintf(path, __LXC_SYS_CLASS_NET_LEN, "/sys/class/net/%s", nic); ret = strnprintf(path, sizeof(path), "/sys/class/net/%s", nic);
if (ret < 0 || (size_t)ret >= __LXC_SYS_CLASS_NET_LEN) if (ret < 0)
return false; return false;
ret = stat(path, &sb); ret = stat(path, &sb);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment