aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--arch.c6
-rw-r--r--conf.c13
-rw-r--r--pasta.c11
-rw-r--r--tap.c5
-rw-r--r--util.c30
-rw-r--r--util.h2
6 files changed, 57 insertions, 10 deletions
diff --git a/arch.c b/arch.c
index 04bebfc..d1dfb73 100644
--- a/arch.c
+++ b/arch.c
@@ -19,6 +19,7 @@
#include <unistd.h>
#include "log.h"
+#include "util.h"
/**
* arch_avx2_exec() - Switch to AVX2 build if supported
@@ -40,7 +41,10 @@ void arch_avx2_exec(char **argv)
if (__builtin_cpu_supports("avx2")) {
char new_path[PATH_MAX + sizeof(".avx2")];
- snprintf(new_path, PATH_MAX + sizeof(".avx2"), "%s.avx2", exe);
+ if (snprintf_check(new_path, PATH_MAX + sizeof(".avx2"),
+ "%s.avx2", exe))
+ die_perror("Can't build AVX2 executable path");
+
execve(new_path, argv, environ);
warn_perror("Can't run AVX2 build, using non-AVX2 version");
}
diff --git a/conf.c b/conf.c
index b3b5342..fa5cec3 100644
--- a/conf.c
+++ b/conf.c
@@ -574,10 +574,15 @@ static void conf_pasta_ns(int *netns_only, char *userns, char *netns,
if (pidval < 0 || pidval > INT_MAX)
die("Invalid PID %s", argv[optind]);
- snprintf(netns, PATH_MAX, "/proc/%ld/ns/net", pidval);
- if (!*userns)
- snprintf(userns, PATH_MAX, "/proc/%ld/ns/user",
- pidval);
+ if (snprintf_check(netns, PATH_MAX,
+ "/proc/%ld/ns/net", pidval))
+ die_perror("Can't build netns path");
+
+ if (!*userns) {
+ if (snprintf_check(userns, PATH_MAX,
+ "/proc/%ld/ns/user", pidval))
+ die_perror("Can't build userns path");
+ }
}
}
diff --git a/pasta.c b/pasta.c
index 307fb4a..a117704 100644
--- a/pasta.c
+++ b/pasta.c
@@ -102,7 +102,9 @@ static int pasta_wait_for_ns(void *arg)
int flags = O_RDONLY | O_CLOEXEC;
char ns[PATH_MAX];
- snprintf(ns, PATH_MAX, "/proc/%i/ns/net", pasta_child_pid);
+ if (snprintf_check(ns, PATH_MAX, "/proc/%i/ns/net", pasta_child_pid))
+ die_perror("Can't build netns path");
+
do {
while ((c->pasta_netns_fd = open(ns, flags)) < 0) {
if (errno != ENOENT)
@@ -239,8 +241,11 @@ void pasta_start_ns(struct ctx *c, uid_t uid, gid_t gid,
c->quiet = 1;
/* Configure user and group mappings */
- snprintf(uidmap, BUFSIZ, "0 %u 1", uid);
- snprintf(gidmap, BUFSIZ, "0 %u 1", gid);
+ if (snprintf_check(uidmap, BUFSIZ, "0 %u 1", uid))
+ die_perror("Can't build uidmap");
+
+ if (snprintf_check(gidmap, BUFSIZ, "0 %u 1", gid))
+ die_perror("Can't build gidmap");
if (write_file("/proc/self/uid_map", uidmap) ||
write_file("/proc/self/setgroups", "deny") ||
diff --git a/tap.c b/tap.c
index c53a39b..cfb82e9 100644
--- a/tap.c
+++ b/tap.c
@@ -1151,8 +1151,9 @@ int tap_sock_unix_open(char *sock_path)
if (*sock_path)
memcpy(path, sock_path, UNIX_PATH_MAX);
- else
- snprintf(path, UNIX_PATH_MAX - 1, UNIX_SOCK_PATH, i);
+ else if (snprintf_check(path, UNIX_PATH_MAX - 1,
+ UNIX_SOCK_PATH, i))
+ die_perror("Can't build UNIX domain socket path");
ex = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
if (ex < 0)
diff --git a/util.c b/util.c
index eba7d52..21ce0a8 100644
--- a/util.c
+++ b/util.c
@@ -749,3 +749,33 @@ void close_open_files(int argc, char **argv)
if (rc)
die_perror("Failed to close files leaked by parent");
}
+
+/**
+ * snprintf_check() - snprintf() wrapper, checking for truncation and errors
+ * @str: Output buffer
+ * @size: Maximum size to write to @str
+ * @format: Message
+ *
+ * Return: false on success, true on truncation or error, sets errno on failure
+ */
+bool snprintf_check(char *str, size_t size, const char *format, ...)
+{
+ va_list ap;
+ int rc;
+
+ va_start(ap, format);
+ rc = vsnprintf(str, size, format, ap);
+ va_end(ap);
+
+ if (rc < 0) {
+ errno = EIO;
+ return true;
+ }
+
+ if ((size_t)rc >= size) {
+ errno = ENOBUFS;
+ return true;
+ }
+
+ return false;
+}
diff --git a/util.h b/util.h
index 2c1e08e..96f178c 100644
--- a/util.h
+++ b/util.h
@@ -11,6 +11,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
+#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
@@ -200,6 +201,7 @@ int write_file(const char *path, const char *buf);
int write_all_buf(int fd, const void *buf, size_t len);
int write_remainder(int fd, const struct iovec *iov, size_t iovcnt, size_t skip);
void close_open_files(int argc, char **argv);
+bool snprintf_check(char *str, size_t size, const char *format, ...);
/**
* af_name() - Return name of an address family