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)
if (dfd_init_pid < 0 || pidfd < 0)
return ret_errno(EBADF);
ret = snprintf(path + STRLITERALLEN("fdinfo/"), INTTYPE_TO_STRLEN(int), "%d", pidfd);
if (ret < 0 || ret > (size_t)INTTYPE_TO_STRLEN(int))
ret = strnprintf(path + STRLITERALLEN("fdinfo/"), INTTYPE_TO_STRLEN(int), "%d", pidfd);
if (ret < 0)
return ret_errno(EIO);
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,
if (ctx->init_pid < 0)
return log_error(-1, "Failed to get init pid");
ret = snprintf(path, sizeof(path), "/proc/%d", ctx->init_pid);
if (ret < 0 || ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "/proc/%d", ctx->init_pid);
if (ret < 0)
return ret_errno(EIO);
ctx->dfd_init_pid = open_at(-EBADF, path,
......@@ -947,8 +947,8 @@ static char *lxc_attach_getpwshell(uid_t uid)
}
/* Finish argument list. */
ret = snprintf(uid_buf, sizeof(uid_buf), "%ld", (long)uid);
if (ret <= 0 || ret >= sizeof(uid_buf))
ret = strnprintf(uid_buf, sizeof(uid_buf), "%ld", (long)uid);
if (ret <= 0)
_exit(EXIT_FAILURE);
/* Try to run getent program. */
......
......@@ -266,8 +266,8 @@ static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
if (!is_set(i, bitarr))
continue;
ret = snprintf(numstr, sizeof(numstr), "%zu", i);
if (ret < 0 || (size_t)ret >= sizeof(numstr))
ret = strnprintf(numstr, sizeof(numstr), "%zu", i);
if (ret < 0)
return NULL;
ret = lxc_append_string(&cpulist, numstr);
......@@ -1053,8 +1053,8 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
}
conf = handler->conf;
len = snprintf(pidstr, sizeof(pidstr), "%d", handler->monitor_pid);
if (len < 0 || (size_t)len >= sizeof(pidstr))
len = strnprintf(pidstr, sizeof(pidstr), "%d", handler->monitor_pid);
if (len < 0)
return;
for (int i = 0; ops->hierarchies[i]; i++) {
......@@ -1471,9 +1471,15 @@ __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops,
if (!handler || !handler->conf)
return ret_set_errno(false, EINVAL);
monitor_len = snprintf(monitor, sizeof(monitor), "%d", handler->monitor_pid);
if (handler->transient_pid > 0)
transient_len = snprintf(transient, sizeof(transient), "%d", handler->transient_pid);
monitor_len = strnprintf(monitor, sizeof(monitor), "%d", handler->monitor_pid);
if (monitor_len < 0)
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++) {
struct hierarchy *h = ops->hierarchies[i];
......@@ -1526,7 +1532,9 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops,
if (!handler || !handler->conf)
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++) {
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
if (ret < 0 && errno != EEXIST)
return log_error_errno(-errno, errno, "Failed to create leaf cgroup \".lxc\"");
pidstr_len = snprintf(pidstr, sizeof(pidstr), INT64_FMT, (int64_t)pid);
if (pidstr_len < 0 || (size_t)pidstr_len >= sizeof(pidstr))
return ret_errno(EIO);
pidstr_len = strnprintf(pidstr, sizeof(pidstr), INT64_FMT, (int64_t)pid);
if (pidstr_len < 0)
return pidstr_len;
ret = lxc_writeat(unified_fd, ".lxc/cgroup.procs", pidstr, pidstr_len);
if (ret < 0)
......@@ -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 *slash = attach_cgroup;
ret = snprintf(attach_cgroup, sizeof(attach_cgroup), ".lxc-%d/cgroup.procs", idx);
if (ret < 0 || (size_t)ret >= sizeof(attach_cgroup))
return ret_errno(EIO);
ret = strnprintf(attach_cgroup, sizeof(attach_cgroup), ".lxc-%d/cgroup.procs", idx);
if (ret < 0)
return ret;
/*
* This shouldn't really happen but the compiler might complain
......@@ -2510,8 +2518,8 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops,
if (!ops->hierarchies)
return true;
len = snprintf(pidstr, sizeof(pidstr), "%d", pid);
if (len < 0 || (size_t)len >= sizeof(pidstr))
len = strnprintf(pidstr, sizeof(pidstr), "%d", pid);
if (len < 0)
return false;
for (int i = 0; ops->hierarchies[i]; i++) {
......@@ -2827,11 +2835,13 @@ static int convert_devpath(const char *invalue, char *dest)
if (ret < 0)
return -1;
ret = snprintf(dest, 50, "%c %d:%d %s", device.type, device.major,
device.minor, device.access);
if (ret < 0 || ret >= 50)
return log_error_errno(-1, ENAMETOOLONG, "Error on configuration value \"%c %d:%d %s\" (max 50 chars)",
device.type, device.major, device.minor, device.access);
ret = strnprintf(dest, 50, "%c %d:%d %s", device.type, device.major,
device.minor, device.access);
if (ret < 0)
return log_error_errno(ret, -ret,
"Error on configuration value \"%c %d:%d %s\" (max 50 chars)",
device.type, device.major, device.minor,
device.access);
return 0;
}
......
......@@ -24,6 +24,7 @@
#include "memory_utils.h"
#include "monitor.h"
#include "state.h"
#include "string_utils.h"
#include "utils.h"
lxc_log_define(commands_utils, lxc);
......@@ -104,8 +105,8 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen,
name = "";
if (hashed_sock_name != NULL) {
ret = snprintf(offset, len, "lxc/%s/%s", hashed_sock_name, suffix);
if (ret < 0 || (size_t)ret >= len)
ret = strnprintf(offset, len, "lxc/%s/%s", hashed_sock_name, suffix);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to create abstract socket name");
return 0;
}
......@@ -116,6 +117,10 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen,
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);
if (ret < 0)
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,
if (ret >= len) {
tmplen = strlen(name) + strlen(lxcpath) + 2;
tmppath = must_realloc(NULL, tmplen);
ret = snprintf(tmppath, tmplen, "%s/%s", lxcpath, name);
if (ret < 0 || (size_t)ret >= tmplen)
ret = strnprintf(tmppath, tmplen, "%s/%s", lxcpath, name);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to create abstract socket name");
hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
ret = snprintf(offset, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
if (ret < 0 || (size_t)ret >= len)
ret = strnprintf(offset, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
if (ret < 0)
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)
if (len < 6 || strncmp(fnam + len - 5, ".conf", 5) != 0)
continue;
len = snprintf(path, PATH_MAX, "%s/%s", dirp, fnam);
if (len < 0 || len >= PATH_MAX)
len = strnprintf(path, sizeof(path), "%s/%s", dirp, fnam);
if (len < 0)
return ret_errno(EIO);
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,
tmp = must_realloc(NULL, len);
if (lxc_config_value_empty(v))
ret = snprintf(tmp, len, "%s =", key);
ret = strnprintf(tmp, len, "%s =", key);
else
ret = snprintf(tmp, len, "%s = %s", key, v);
if (ret < 0 || ret >= len)
ret = strnprintf(tmp, len, "%s = %s", key, v);
if (ret < 0)
return false;
/* Save the line verbatim into unexpanded_conf */
......@@ -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;
olddir = must_realloc(NULL, olddirlen + 1);
ret = snprintf(olddir, olddirlen + 1, "%s=%s/%s", ovldir, oldpath,
oldname);
if (ret < 0 || ret >= olddirlen + 1)
ret = strnprintf(olddir, olddirlen + 1, "%s=%s/%s", ovldir, oldpath, oldname);
if (ret < 0)
return false;
newdirlen = strlen(ovldir) + strlen(newpath) + strlen(newname) + 2;
newdir = must_realloc(NULL, newdirlen + 1);
ret = snprintf(newdir, newdirlen + 1, "%s=%s/%s", ovldir, newpath,
newname);
if (ret < 0 || ret >= newdirlen + 1)
ret = strnprintf(newdir, newdirlen + 1, "%s=%s/%s", ovldir, newpath, newname);
if (ret < 0)
return false;
if (!conf->unexpanded_config)
......@@ -3338,14 +3336,14 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
olddirlen = strlen(oldpath) + strlen(oldname) + 1;
olddir = must_realloc(NULL, olddirlen + 1);
ret = snprintf(olddir, olddirlen + 1, "%s/%s", oldpath, oldname);
if (ret < 0 || ret >= olddirlen + 1)
ret = strnprintf(olddir, olddirlen + 1, "%s/%s", oldpath, oldname);
if (ret < 0)
return false;
newdirlen = strlen(newpath) + strlen(newname) + 1;
newdir = must_realloc(NULL, newdirlen + 1);
ret = snprintf(newdir, newdirlen + 1, "%s/%s", newpath, newname);
if (ret < 0 || ret >= newdirlen + 1)
ret = strnprintf(newdir, newdirlen + 1, "%s/%s", newpath, newname);
if (ret < 0)
return false;
if (!conf->unexpanded_config)
......@@ -3877,10 +3875,10 @@ static int get_config_idmaps(const char *key, char *retv, int inlen,
listlen = lxc_list_len(&c->id_map);
lxc_list_for_each(it, &c->id_map) {
struct id_map *map = it->elem;
ret = snprintf(buf, __LXC_IDMAP_STR_BUF, "%c %lu %lu %lu",
(map->idtype == ID_TYPE_UID) ? 'u' : 'g',
map->nsid, map->hostid, map->range);
if (ret < 0 || ret >= __LXC_IDMAP_STR_BUF)
ret = strnprintf(buf, sizeof(buf), "%c %lu %lu %lu",
(map->idtype == ID_TYPE_UID) ? 'u' : 'g',
map->nsid, map->hostid, map->range);
if (ret < 0)
return ret_errno(EIO);
strprint(retv, inlen, "%s%s", buf, (listlen-- > 1) ? "\n" : "");
......
......@@ -768,18 +768,17 @@ bool new_hwaddr(char *hwaddr)
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);
#else
(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);
#endif
if (ret < 0 || ret >= 18) {
return log_error_errno(false, EIO, "Failed to call snprintf()");
}
if (ret < 0)
return log_error_errno(false, EIO, "Failed to call strnprintf()");
return true;
}
......
......@@ -83,8 +83,8 @@ static int load_tty_major_minor(char *directory, char *output, int len)
char path[PATH_MAX];
ssize_t ret;
ret = snprintf(path, sizeof(path), "%s/tty.info", directory);
if (ret < 0 || (size_t)ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "%s/tty.info", directory);
if (ret < 0)
return ret_errno(EIO);
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,
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);
if (ret < 0 || ret >= PATH_MAX)
ret = strnprintf(log, sizeof(log), "%s/%s.log", opts->user->directory, opts->action);
if (ret < 0)
return ret_errno(EIO);
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,
continue;
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
ret = snprintf(arg, sizeof(arg), "%s:%s", mntent.mnt_dir, mntent.mnt_fsname);
if (ret < 0 || ret >= sizeof(arg))
ret = strnprintf(arg, sizeof(arg), "%s:%s", mntent.mnt_dir, mntent.mnt_fsname);
if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create mount entry");
DECLARE_ARG("--ext-mount-map");
......@@ -386,8 +386,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (init_pid < 0)
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);
if (ret < 0 || (size_t)ret >= sizeof(init_pid_str))
ret = strnprintf(init_pid_str, sizeof(init_pid_str), "%d", init_pid);
if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create entry for init pid of container");
DECLARE_ARG("-t");
......@@ -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");
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
ret = snprintf(log, sizeof(log), "/sys/fs/cgroup/freezer/%s", freezer_relative);
if (ret < 0 || ret >= sizeof(log))
ret = strnprintf(log, sizeof(log), "/sys/fs/cgroup/freezer/%s", freezer_relative);
if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to freezer cgroup entry");
if (!opts->user->disable_skip_in_flight &&
......@@ -464,15 +464,15 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (opts->console_fd < 0)
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);
if (ret < 0 || ret >= sizeof(buf))
ret = strnprintf(buf, sizeof(buf), "fd[%d]:%s", opts->console_fd, ttys);
if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create console entry");
DECLARE_ARG("--inherit-fd");
DECLARE_ARG(buf);
}
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");
DECLARE_ARG("--ext-mount-map");
......@@ -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)
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
ret = snprintf(buf, sizeof(buf), "selinux:%s", lxc_conf->lsm_se_context);
if (ret < 0 || ret >= sizeof(buf))
ret = strnprintf(buf, sizeof(buf), "selinux:%s", lxc_conf->lsm_se_context);
if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to create lsm entry");
DECLARE_ARG("--lsm-profile");
......@@ -513,8 +513,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (retlen >= sizeof(eth))
return log_error_errno(-E2BIG, E2BIG, "Failed to append veth device name");
} else {
ret = snprintf(eth, sizeof(eth), "eth%d", netnr);
if (ret < 0 || ret >= sizeof(eth))
ret = strnprintf(eth, sizeof(eth), "eth%d", netnr);
if (ret < 0)
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,
if (n->link[0] != '\0') {
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
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 {
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
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");
TRACE("Added veth device entry %s", buf);
......@@ -544,8 +544,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (n->link[0] == '\0')
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);
if (ret < 0 || ret >= sizeof(buf))
ret = strnprintf(buf, sizeof(buf), "macvlan[%s]:%s", eth, n->link);
if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to add macvlan entry");
TRACE("Added macvlan device entry %s", buf);
......@@ -574,8 +574,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
if (lxc_log_trace()) {
buf[0] = 0;
for (int i = 0, pos = 0; i < args->argc && args->argv[i]; i++) {
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s ", args->argv[i]);
if (ret < 0 || ret >= sizeof(buf) - pos)
ret = strnprintf(buf + pos, sizeof(buf) - pos, "%s ", args->argv[i]);
if (ret < 0)
return log_error_errno(-EIO, EIO, "Failed to reorder entries");
else
pos += ret;
......@@ -857,8 +857,8 @@ static bool restore_net_info(struct lxc_container *c)
if (netdev->type != LXC_NET_VETH)
continue;
ret = snprintf(template, sizeof(template), "vethXXXXXX");
if (ret < 0 || ret >= sizeof(template))
ret = strnprintf(template, sizeof(template), "vethXXXXXX");
if (ret < 0)
goto out_unlock;
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_
ERROR("criu process exited %d, output:\n%s", WEXITSTATUS(status), buf);
goto out_fini_handler;
} else {
ret = snprintf(buf, sizeof(buf), "/proc/self/task/%lu/children", (unsigned long)syscall(__NR_gettid));
if (ret < 0 || ret >= sizeof(buf)) {
ERROR("snprintf'd too many characters: %d", ret);
ret = strnprintf(buf, sizeof(buf), "/proc/self/task/%lu/children", (unsigned long)syscall(__NR_gettid));
if (ret < 0) {
ERROR("strnprintf'd too many characters: %d", ret);
goto out_fini_handler;
}
......@@ -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
* assign the return here to silence potential.
*/
ret = snprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name);
if (ret < 0 || (size_t)ret >= sizeof(title))
ret = strnprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name);
if (ret < 0)
INFO("Setting truncated process name");
ret = setproctitle(title);
......@@ -1149,9 +1149,9 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char *
return 0;
}
ret = snprintf(path, sizeof(path), "/proc/%d/root/dev/console", c->init_pid(c));
if (ret < 0 || ret >= sizeof(path)) {
ERROR("snprintf'd too many characters: %d", ret);
ret = strnprintf(path, sizeof(path), "/proc/%d/root/dev/console", c->init_pid(c));
if (ret < 0) {
ERROR("strnprintf'd too many characters: %d", ret);
return -1;
}
......@@ -1161,17 +1161,17 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char *
return -1;
}
ret = snprintf(path, sizeof(path), "%s/tty.info", directory);
if (ret < 0 || ret >= sizeof(path)) {
ERROR("snprintf'd too many characters: %d", ret);
ret = strnprintf(path, sizeof(path), "%s/tty.info", directory);
if (ret < 0) {
ERROR("strnprintf'd too many characters: %d", ret);
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_dev);
if (ret < 0 || ret >= sizeof(path)) {
ERROR("snprintf'd too many characters: %d", ret);
if (ret < 0) {
ERROR("strnprintf'd too many characters: %d", ret);
return -1;
}
......@@ -1313,8 +1313,8 @@ bool __criu_dump(struct lxc_container *c, struct migrate_opts *opts)
char path[PATH_MAX];
int ret;
ret = snprintf(path, sizeof(path), "%s/inventory.img", opts->directory);
if (ret < 0 || ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "%s/inventory.img", opts->directory);
if (ret < 0)
return false;
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)
if (fd < 0)
return -errno;
len = snprintf(buf, sizeof(buf), "%d %" PRId64 " %" PRId64, clk_id, s_offset, ns_offset);
if (len < 0 || len >= sizeof(buf))
len = strnprintf(buf, sizeof(buf), "%d %" PRId64 " %" PRId64, clk_id, s_offset, ns_offset);
if (len < 0)
return ret_errno(EFBIG);
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
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;
......@@ -346,6 +346,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,
......@@ -572,10 +576,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);
......
......@@ -103,17 +103,17 @@ static char *lxclock_name(const char *p, const char *n)
if (!dest)
return NULL;
ret = snprintf(dest, len, "%s/lxc/lock/%s", rundir, p);
if (ret < 0 || (size_t)ret >= len)
return ret_set_errno(NULL, EIO);
ret = strnprintf(dest, len, "%s/lxc/lock/%s", rundir, p);
if (ret < 0)
return NULL;
ret = mkdir_p(dest, 0755);
if (ret < 0)
return NULL;
ret = snprintf(dest, len, "%s/lxc/lock/%s/.%s", rundir, p, n);
if (ret < 0 || (size_t)ret >= len)
return ret_set_errno(NULL, EIO);
ret = strnprintf(dest, len, "%s/lxc/lock/%s/.%s", rundir, p, n);
if (ret < 0)
return NULL;
return move_ptr(dest);
}
......
......@@ -50,8 +50,8 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
return -1;
if (do_mkdirp) {
ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath);
if (ret < 0 || (size_t)ret >= fifo_path_sz) {
ret = strnprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath);
if (ret < 0) {
ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
free(rundir);
return -1;
......@@ -63,8 +63,8 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
return ret;
}
}
ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath);
if (ret < 0 || (size_t)ret >= fifo_path_sz) {
ret = strnprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath);
if (ret < 0) {
ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
free(rundir);
return -1;
......@@ -163,27 +163,23 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr)
/* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */
len = strlen(lxcpath) + 18;
path = must_realloc(NULL, len);
ret = snprintf(path, len, "lxc/%s/monitor-sock", lxcpath);
if (ret < 0 || (size_t)ret >= len) {
ret = strnprintf(path, len, "lxc/%s/monitor-sock", lxcpath);
if (ret < 0) {
ERROR("Failed to create name for monitor socket");
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
* is absolutely intentional. For further info read the comment for this
* function above!
*/
len = sizeof(addr->sun_path) - 1;
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) {
ERROR("Failed to create hashed name for monitor socket");
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 */
......@@ -353,8 +349,8 @@ int lxc_monitord_spawn(const char *lxcpath)
close(pipefd[0]);
ret = snprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]);
if (ret < 0 || ret >= sizeof(pipefd_str)) {
ret = strnprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]);
if (ret < 0) {
ERROR("Failed to create pid argument to pass to monitord");
_exit(EXIT_FAILURE);
}
......
......@@ -138,8 +138,8 @@ static int __fs_prepare(const char *fs_name, int fd_from)
* only use fds for mount.
*/
if (fd_from >= 0) {
ret = snprintf(source, sizeof(source), "/proc/self/fd/%d", fd_from);
if (ret < 0 || ret >= sizeof(source))
ret = strnprintf(source, sizeof(source), "/proc/self/fd/%d", fd_from);
if (ret < 0)
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)
if (family != AF_INET && family != AF_INET6)
return ret_set_errno(-1, EINVAL);
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
"forwarding");
if (ret < 0 || (size_t)ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
"forwarding");
if (ret < 0)
return ret_set_errno(-1, E2BIG);
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)
return 0;
/* Check vlan filtering is enabled on parent bridge. */
rc = snprintf(path, sizeof(path), "/sys/class/net/%s/bridge/vlan_filtering", netdev->link);
if (rc < 0 || (size_t)rc >= sizeof(path))
rc = strnprintf(path, sizeof(path), "/sys/class/net/%s/bridge/vlan_filtering", netdev->link);
if (rc < 0)
return -1;
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)
unsigned short default_pvid;
/* Get the bridge's default VLAN PVID. */
rc = snprintf(path, sizeof(path), "/sys/class/net/%s/bridge/default_pvid", netdev->link);
if (rc < 0 || (size_t)rc >= sizeof(path))
rc = strnprintf(path, sizeof(path), "/sys/class/net/%s/bridge/default_pvid", netdev->link);
if (rc < 0)
return -1;
rc = lxc_read_from_file(path, buf, sizeof(buf));
......@@ -443,8 +443,8 @@ static int lxc_ovs_setup_bridge_vlan_exec(void *data)
char buf[5];
int rc;
rc = snprintf(buf, sizeof(buf), "%u", args->vlan_id);
if (rc < 0 || (size_t)rc >= sizeof(buf))
rc = strnprintf(buf, sizeof(buf), "%u", args->vlan_id);
if (rc < 0)
return log_error_errno(-1, EINVAL, "Failed to parse ovs bridge vlan \"%d\"", args->vlan_id);
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)
char buf[5]; /* Sufficient size to fit max VLAN ID (4094) null char. */
int rc;
rc = snprintf(buf, sizeof(buf), "%u", vlan_id);
if (rc < 0 || (size_t)rc >= sizeof(buf)) {
rc = strnprintf(buf, sizeof(buf), "%u", vlan_id);
if (rc < 0) {
free_ovs_veth_vlan_args(&args);
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
if (handler->conf->reboot)
lxc_netdev_delete_by_name(veth1);
} else {
err = snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX");
if (err < 0 || (size_t)err >= sizeof(veth1buf))
err = strnprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX");
if (err < 0)
return -1;
veth1 = lxc_ifname_alnum_case_sensitive(veth1buf);
......@@ -565,8 +565,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ);
}
err = snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
if (err < 0 || (size_t)err >= sizeof(veth2buf))
err = strnprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
if (err < 0)
return -1;
veth2 = lxc_ifname_alnum_case_sensitive(veth2buf);
......@@ -781,8 +781,8 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
return -1;
}
err = snprintf(peer, sizeof(peer), "mcXXXXXX");
if (err < 0 || (size_t)err >= sizeof(peer))
err = strnprintf(peer, sizeof(peer), "mcXXXXXX");
if (err < 0)
return -1;
if (!lxc_ifname_alnum_case_sensitive(peer))
......@@ -931,8 +931,8 @@ static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *ne
return -1;
}
err = snprintf(peer, sizeof(peer), "ipXXXXXX");
if (err < 0 || (size_t)err >= sizeof(peer))
err = strnprintf(peer, sizeof(peer), "ipXXXXXX");
if (err < 0)
return -1;
if (!lxc_ifname_alnum_case_sensitive(peer))
......@@ -1006,9 +1006,9 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
return -1;
}
err = snprintf(peer, sizeof(peer), "vlan%d-%d",
netdev->priv.vlan_attr.vid, vlan_cntr++);
if (err < 0 || (size_t)err >= sizeof(peer))
err = strnprintf(peer, sizeof(peer), "vlan%d-%d",
netdev->priv.vlan_attr.vid, vlan_cntr++);
if (err < 0)
return -1;
err = lxc_vlan_create(netdev->link, peer, netdev->priv.vlan_attr.vid);
......@@ -1489,8 +1489,8 @@ char *is_wlan(const char *ifname)
len = strlen(ifname) + strlen(PHYSNAME) - 1;
path = must_realloc(NULL, len + 1);
ret = snprintf(path, len, PHYSNAME, ifname);
if (ret < 0 || (size_t)ret >= len)
ret = strnprintf(path, len, PHYSNAME, ifname);
if (ret < 0)
return NULL;
f = fopen(path, "re");
......@@ -2217,9 +2217,10 @@ static int ip_forwarding_set(const char *ifname, int family, int flag)
if (family != AF_INET && family != AF_INET6)
return -EINVAL;
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname, "forwarding");
if (ret < 0 || (size_t)ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
"forwarding");
if (ret < 0)
return -E2BIG;
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)
if (family != AF_INET && family != AF_INET6)
return -EINVAL;
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0 || (size_t)ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0)
return -E2BIG;
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)
if (family != AF_INET && family != AF_INET6)
return ret_set_errno(-1, EINVAL);
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0 || (size_t)ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0)
return ret_set_errno(-1, E2BIG);
return lxc_read_file_expect(path, buf, 1, "1");
......@@ -2629,9 +2630,9 @@ bool is_ovs_bridge(const char *bridge)
struct stat sb;
char brdirname[22 + IFNAMSIZ + 1] = {0};
ret = snprintf(brdirname, 22 + IFNAMSIZ + 1, "/sys/class/net/%s/bridge",
bridge);
if (ret < 0 || (size_t)ret >= 22 + IFNAMSIZ + 1)
ret = strnprintf(brdirname, 22 + IFNAMSIZ + 1,
"/sys/class/net/%s/bridge", bridge);
if (ret < 0)
return false;
ret = stat(brdirname, &sb);
......@@ -2795,28 +2796,24 @@ char *lxc_ifname_alnum_case_sensitive(char *template)
int setup_private_host_hw_addr(char *veth1)
{
int err, sockfd;
__do_close int sockfd = -EBADF;
int err;
struct ifreq ifr;
sockfd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sockfd < 0)
return -errno;
err = snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
if (err < 0 || (size_t)err >= IFNAMSIZ) {
close(sockfd);
return -E2BIG;
}
err = strnprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
if (err < 0)
return err;
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) {
close(sockfd);
if (err < 0)
return -errno;
}
ifr.ifr_hwaddr.sa_data[0] = 0xfe;
err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
close(sockfd);
if (err < 0)
return -errno;
......@@ -2910,8 +2907,8 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
_exit(EXIT_FAILURE);
}
ret = snprintf(pidstr, sizeof(pidstr), "%d", pid);
if (ret < 0 || ret >= sizeof(pidstr))
ret = strnprintf(pidstr, sizeof(pidstr), "%d", pid);
if (ret < 0)
_exit(EXIT_FAILURE);
pidstr[sizeof(pidstr) - 1] = '\0';
......@@ -3108,9 +3105,9 @@ static bool lxc_delete_network_unpriv(struct lxc_handler *handler)
if (handler->nsfd[LXC_NS_NET] < 0)
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",
lxc_raw_getpid(), handler->nsfd[LXC_NS_NET]);
if (ret < 0 || ret >= sizeof(netns_path))
ret = strnprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d",
lxc_raw_getpid(), handler->nsfd[LXC_NS_NET]);
if (ret < 0)
return false;
lxc_list_for_each(iterator, network) {
......
......@@ -98,9 +98,9 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
if (memfd < 0) {
char template[PATH_MAX];
ret = snprintf(template, sizeof(template),
P_tmpdir "/.%s_XXXXXX", memfd_name);
if (ret < 0 || (size_t)ret >= sizeof(template))
ret = strnprintf(template, sizeof(template),
P_tmpdir "/.%s_XXXXXX", memfd_name);
if (ret < 0)
return;
tmpfd = lxc_make_tmpfile(template, true);
......@@ -151,8 +151,8 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
} else {
char procfd[LXC_PROC_PID_FD_LEN];
ret = snprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", tmpfd);
if (ret < 0 || (size_t)ret >= sizeof(procfd))
ret = strnprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", tmpfd);
if (ret < 0)
return;
execfd = open(procfd, O_PATH | O_CLOEXEC);
......
......@@ -1418,7 +1418,13 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
resp->id = req_id = 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);
if (fd_pid < 0) {
seccomp_notify_default_answer(fd, req, resp, hdlr);
......@@ -1426,7 +1432,13 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
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);
if (fd_mem < 0) {
seccomp_notify_default_answer(fd, req, resp, hdlr);
......
......@@ -183,8 +183,8 @@ static bool match_dlog_fds(struct dirent *direntp)
ssize_t linklen;
int ret;
ret = snprintf(path, PATH_MAX, "/proc/self/fd/%s", direntp->d_name);
if (ret < 0 || ret >= PATH_MAX)
ret = strnprintf(path, sizeof(path), "/proc/self/fd/%s", direntp->d_name);
if (ret < 0)
return log_error(false, "Failed to create file descriptor name");
linklen = readlink(path, link, PATH_MAX);
......@@ -1147,9 +1147,9 @@ static int do_start(void *data)
if (handler->daemonize && !handler->conf->autodev) {
char path[PATH_MAX];
ret = snprintf(path, sizeof(path), "%s/dev/null",
handler->conf->rootfs.mount);
if (ret < 0 || ret >= sizeof(path))
ret = strnprintf(path, sizeof(path), "%s/dev/null",
handler->conf->rootfs.mount);
if (ret < 0)
goto out_warn_father;
ret = access(path, F_OK);
......@@ -1749,8 +1749,8 @@ static int lxc_spawn(struct lxc_handler *handler)
if (!lxc_can_use_pidfd(handler->pidfd))
close_prot_errno_disarm(handler->pidfd);
ret = snprintf(pidstr, 20, "%d", handler->pid);
if (ret < 0 || ret >= 20)
ret = strnprintf(pidstr, 20, "%d", handler->pid);
if (ret < 0)
goto out_delete_net;
ret = setenv("LXC_PID", pidstr, 1);
......@@ -2200,8 +2200,8 @@ static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
}
INFO("Destroyed rootfs for container \"%s\"", name);
ret = snprintf(destroy, PATH_MAX, "%s/%s", handler->lxcpath, name);
if (ret < 0 || ret >= PATH_MAX) {
ret = strnprintf(destroy, sizeof(destroy), "%s/%s", handler->lxcpath, name);
if (ret < 0) {
ERROR("Error destroying directory for container \"%s\"", name);
return;
}
......
......@@ -276,9 +276,9 @@ char *lxc_deslashify(const char *path)
char *lxc_append_paths(const char *first, const char *second)
{
__do_free char *result = NULL;
int ret;
size_t len;
char *result = NULL;
int pattern_type = 0;
len = strlen(first) + strlen(second) + 1;
......@@ -287,20 +287,18 @@ char *lxc_append_paths(const char *first, const char *second)
pattern_type = 1;
}
result = calloc(1, len);
result = zalloc(len);
if (!result)
return NULL;
if (pattern_type == 0)
ret = snprintf(result, len, "%s%s", first, second);
ret = strnprintf(result, len, "%s%s", first, second);
else
ret = snprintf(result, len, "%s/%s", first, second);
if (ret < 0 || (size_t)ret >= len) {
free(result);
ret = strnprintf(result, len, "%s/%s", first, second);
if (ret < 0)
return NULL;
}
return result;
return move_ptr(result);
}
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)
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 */
......@@ -209,8 +209,8 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
len = strlen(terminal->log_path) + sizeof(".1");
tmp = must_realloc(NULL, len);
ret = snprintf(tmp, len, "%s.1", terminal->log_path);
if (ret < 0 || (size_t)ret >= len)
ret = strnprintf(tmp, len, "%s.1", terminal->log_path);
if (ret < 0)
return -EFBIG;
close(terminal->log_fd);
......
......@@ -84,8 +84,8 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev,
!strcmp(direntp->d_name, ".."))
continue;
rc = snprintf(pathname, PATH_MAX, "%s/%s", dirname, direntp->d_name);
if (rc < 0 || rc >= PATH_MAX) {
rc = strnprintf(pathname, sizeof(pathname), "%s/%s", dirname, direntp->d_name);
if (rc < 0) {
ERROR("The name of path is too long");
failed = 1;
continue;
......@@ -267,8 +267,8 @@ char *get_rundir(void)
if (!rundir)
return NULL;
ret = snprintf(rundir, len, "%s/.cache/lxc/run/", homedir);
if (ret < 0 || (size_t)ret >= len)
ret = strnprintf(rundir, len, "%s/.cache/lxc/run/", homedir);
if (ret < 0)
return ret_set_errno(NULL, EIO);
return move_ptr(rundir);
......@@ -660,8 +660,8 @@ bool switch_to_ns(pid_t pid, const char *ns)
+ LXC_NAMESPACE_NAME_MAX];
/* Switch to new ns */
ret = snprintf(nspath, sizeof(nspath), "/proc/%d/ns/%s", pid, ns);
if (ret < 0 || ret >= sizeof(nspath))
ret = strnprintf(nspath, sizeof(nspath), "/proc/%d/ns/%s", pid, ns);
if (ret < 0)
return false;
fd = open(nspath, O_RDONLY | O_CLOEXEC);
......@@ -734,11 +734,10 @@ char *on_path(const char *cmd, const char *rootfs)
lxc_iterate_parts(entry, path, ":") {
if (rootfs)
ret = snprintf(cmdpath, PATH_MAX, "%s/%s/%s", rootfs,
entry, cmd);
ret = strnprintf(cmdpath, sizeof(cmdpath), "%s/%s/%s", rootfs, entry, cmd);
else
ret = snprintf(cmdpath, PATH_MAX, "%s/%s", entry, cmd);
if (ret < 0 || ret >= PATH_MAX)
ret = strnprintf(cmdpath, sizeof(cmdpath), "%s/%s", entry, cmd);
if (ret < 0)
continue;
if (access(cmdpath, X_OK) == 0)
......@@ -788,8 +787,8 @@ char *choose_init(const char *rootfs)
else
tmp = empty;
ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, SBINDIR, "/init.lxc");
if (ret < 0 || ret >= PATH_MAX) {
ret = strnprintf(retv, PATH_MAX, "%s/%s/%s", tmp, SBINDIR, "/init.lxc");
if (ret < 0) {
ERROR("The name of path is too long");
goto out1;
}
......@@ -797,8 +796,8 @@ char *choose_init(const char *rootfs)
if (access(retv, X_OK) == 0)
return retv;
ret = snprintf(retv, PATH_MAX, "%s/%s/%s", tmp, LXCINITDIR, "/lxc/lxc-init");
if (ret < 0 || ret >= PATH_MAX) {
ret = strnprintf(retv, PATH_MAX, "%s/%s/%s", tmp, LXCINITDIR, "/lxc/lxc-init");
if (ret < 0) {
ERROR("The name of path is too long");
goto out1;
}
......@@ -806,8 +805,8 @@ char *choose_init(const char *rootfs)
if (access(retv, X_OK) == 0)
return retv;
ret = snprintf(retv, PATH_MAX, "%s/usr/lib/lxc/lxc-init", tmp);
if (ret < 0 || ret >= PATH_MAX) {
ret = strnprintf(retv, PATH_MAX, "%s/usr/lib/lxc/lxc-init", tmp);
if (ret < 0) {
ERROR("The name of path is too long");
goto out1;
}
......@@ -815,8 +814,8 @@ char *choose_init(const char *rootfs)
if (access(retv, X_OK) == 0)
return retv;
ret = snprintf(retv, PATH_MAX, "%s/sbin/lxc-init", tmp);
if (ret < 0 || ret >= PATH_MAX) {
ret = strnprintf(retv, PATH_MAX, "%s/sbin/lxc-init", tmp);
if (ret < 0) {
ERROR("The name of path is too long");
goto out1;
}
......@@ -834,8 +833,8 @@ char *choose_init(const char *rootfs)
if (rootfs)
goto out1;
ret = snprintf(retv, PATH_MAX, "/init.lxc.static");
if (ret < 0 || ret >= PATH_MAX) {
ret = strnprintf(retv, PATH_MAX, "/init.lxc.static");
if (ret < 0) {
WARN("Nonsense - name /lxc.init.static too long");
goto out1;
}
......@@ -874,8 +873,8 @@ char *get_template_path(const char *t)
if (!tpath)
return NULL;
ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
if (ret < 0 || ret >= len) {
ret = strnprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
if (ret < 0) {
free(tpath);
return NULL;
}
......@@ -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));
if (source_fd < 0)
return -errno;
ret = snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd);
if (ret < 0 || ret >= sizeof(src_buf))
ret = strnprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd);
if (ret < 0)
return -EIO;
} else {
src_buf[0] = '\0';
......@@ -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));
if (target_fd < 0)
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);
if (ret < 0 || ret >= sizeof(tgt_buf))
ret = strnprintf(tgt_buf, sizeof(tgt_buf), "/proc/self/fd/%d", target_fd);
if (ret < 0)
return -EIO;
if (!is_empty_string(src_buf))
......@@ -1163,8 +1162,8 @@ int safe_mount(const char *src, const char *dest, const char *fstype,
if (srcfd < 0)
return srcfd;
ret = snprintf(srcbuf, sizeof(srcbuf), "/proc/self/fd/%d", srcfd);
if (ret < 0 || ret >= (int)sizeof(srcbuf)) {
ret = strnprintf(srcbuf, sizeof(srcbuf), "/proc/self/fd/%d", srcfd);
if (ret < 0) {
close(srcfd);
ERROR("Out of memory");
return -EINVAL;
......@@ -1183,8 +1182,8 @@ int safe_mount(const char *src, const char *dest, const char *fstype,
return destfd;
}
ret = snprintf(destbuf, sizeof(destbuf), "/proc/self/fd/%d", destfd);
if (ret < 0 || ret >= (int)sizeof(destbuf)) {
ret = strnprintf(destbuf, sizeof(destbuf), "/proc/self/fd/%d", destfd);
if (ret < 0) {
if (srcfd != -1)
close(srcfd);
......@@ -1266,8 +1265,8 @@ bool task_blocks_signal(pid_t pid, int signal)
size_t n = 0;
bool bret = false;
ret = snprintf(status, __PROC_STATUS_LEN, "/proc/%d/status", pid);
if (ret < 0 || ret >= __PROC_STATUS_LEN)
ret = strnprintf(status, sizeof(status), "/proc/%d/status", pid);
if (ret < 0)
return bret;
f = fopen(status, "re");
......@@ -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
* string.
*/
ret = snprintf(path, __NS_PATH_LEN, "/proc/%d/ns%s%s", pid,
!ns || strcmp(ns, "") == 0 ? "" : "/",
!ns || strcmp(ns, "") == 0 ? "" : ns);
if (ret < 0 || (size_t)ret >= __NS_PATH_LEN)
ret = strnprintf(path, sizeof(path), "/proc/%d/ns%s%s", pid,
!ns || strcmp(ns, "") == 0 ? "" : "/",
!ns || strcmp(ns, "") == 0 ? "" : ns);
if (ret < 0)
return ret_errno(EIO);
return open(path, O_RDONLY | O_CLOEXEC);
......@@ -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);
if (ret < 0 || ret >= LO_NAME_SIZE) {
ret = strnprintf(loop_name, LO_NAME_SIZE, "/dev/%s", dp->d_name);
if (ret < 0) {
close(fd);
fd = -1;
continue;
......@@ -1439,15 +1438,15 @@ static int lxc_get_unused_loop_dev(char *name_loop)
goto on_error;
}
ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr);
if (ret < 0 || ret >= LO_NAME_SIZE)
ret = strnprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr);
if (ret < 0)
goto on_error;
fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC);
if (fd_tmp < 0) {
/* 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);
if (ret < 0 || ret >= LO_NAME_SIZE)
ret = strnprintf(name_loop, LO_NAME_SIZE, "/dev/block/loop%d", loop_nr);
if (ret < 0)
goto on_error;
fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC);
......@@ -1633,8 +1632,8 @@ bool lxc_nic_exists(char *nic)
if (!strcmp(nic, "none"))
return true;
ret = snprintf(path, __LXC_SYS_CLASS_NET_LEN, "/sys/class/net/%s", nic);
if (ret < 0 || (size_t)ret >= __LXC_SYS_CLASS_NET_LEN)
ret = strnprintf(path, sizeof(path), "/sys/class/net/%s", nic);
if (ret < 0)
return false;
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