user: simplify creation of uid/gid maps
authorRobert Swiecki <robert@swiecki.net>
Sun, 11 Feb 2018 03:02:14 +0000 (04:02 +0100)
committerRobert Swiecki <robert@swiecki.net>
Sun, 11 Feb 2018 03:02:14 +0000 (04:02 +0100)
net.cc
subproc.cc
subproc.h
user.cc

diff --git a/net.cc b/net.cc
index 123e0f88a5b490b434a768772bc2f0d05735e990..46c70de61ddedbac547b910964381091f9b72be1 100644 (file)
--- a/net.cc
+++ b/net.cc
@@ -135,8 +135,7 @@ bool initNsFromParent(nsjconf_t* nsjconf, int pid) {
        char pid_str[256];
        snprintf(pid_str, sizeof(pid_str), "%d", pid);
 
-       const char* argv[] = {"/sbin/ip", "link", "add", "link", (char*)nsjconf->iface_vs.c_str(),
-           "name", IFACE_NAME, "netns", pid_str, "type", "macvlan", "mode", "bridge", NULL};
+       const std::vector<std::string> argv {"/sbin/ip", "link", "add", "link", (char*)nsjconf->iface_vs.c_str(), "name", IFACE_NAME, "netns", pid_str, "type", "macvlan", "mode", "bridge" };
        if (subproc::systemExe(argv, environ) != 0) {
                LOG_E("Couldn't create MACVTAP interface for '%s'", nsjconf->iface_vs.c_str());
                return false;
index 78a1ee10ae702de82b89d94161d99cb8c79176d3..f045dd69c6134e39b34a9dfeefac2618f4ca9605 100644 (file)
@@ -42,6 +42,7 @@
 #include <unistd.h>
 
 #include <string>
+#include <vector>
 
 #include "cgroup.h"
 #include "contain.h"
@@ -487,9 +488,15 @@ pid_t cloneProc(uintptr_t flags) {
        return 0;
 }
 
-int systemExe(const char** argv, char** env) {
+int systemExe(const std::vector<std::string>& args, char** env) {
        bool exec_failed = false;
 
+       std::vector<const char*> argv;
+       for (const auto& a : args) {
+                       argv.push_back(a.c_str());
+       }
+       argv.push_back(nullptr);
+
        int sv[2];
        if (pipe2(sv, O_CLOEXEC) == -1) {
                PLOG_W("pipe2(sv, O_CLOEXEC");
@@ -506,7 +513,7 @@ int systemExe(const char** argv, char** env) {
 
        if (pid == 0) {
                close(sv[0]);
-               execve(argv[0], (char* const*)argv, (char* const*)env);
+               execve(argv[0], (char* const*)argv.data(), (char* const*)env);
                PLOG_W("execve('%s')", argv[0]);
                util::writeToFd(sv[1], "A", 1);
                exit(0);
index 8c8caaf624007fd25fc4ccca9dd29fe22525a721..39acc8c2ba0cab26a3c43a36b403262bdb62f0d0 100644 (file)
--- a/subproc.h
+++ b/subproc.h
@@ -26,6 +26,9 @@
 #include <stdbool.h>
 #include <unistd.h>
 
+#include <string>
+#include <vector>
+
 #include "nsjail.h"
 
 namespace subproc {
@@ -36,7 +39,7 @@ void displayProc(nsjconf_t* nsjconf);
 void killAll(nsjconf_t* nsjconf);
 /* Returns the exit code of the first failing subprocess, or 0 if none fail */
 int reapProc(nsjconf_t* nsjconf);
-int systemExe(const char** argv, char** env);
+int systemExe(const std::vector<std::string>& args, char** env);
 pid_t cloneProc(uintptr_t flags);
 
 }  // namespace subproc
diff --git a/user.cc b/user.cc
index 9c2963f15ffaf404eb9919ed9898617e72930d64..5d90704570c2259572f5197abcdf5e9672495a0c 100644 (file)
--- a/user.cc
+++ b/user.cc
@@ -97,26 +97,27 @@ static bool setGroups(pid_t pid) {
 }
 
 static bool uidMapSelf(nsjconf_t* nsjconf, pid_t pid) {
-       char fname[PATH_MAX];
-       snprintf(fname, sizeof(fname), "/proc/%d/uid_map", pid);
-
-       char map[4096] = {[0] = '\0'};
-
+       std::string map;
        for (const auto& uid : nsjconf->uids) {
                if (uid.is_newidmap) {
                        continue;
                }
-               util::sSnPrintf(map, sizeof(map), "%lu %lu %zu\n", (unsigned long)uid.inside_id,
-                   (unsigned long)uid.outside_id, uid.count);
-       }
-
-       if (strlen(map) == 0) {
+               map.append(std::to_string(uid.inside_id));
+               map.append(" ");
+               map.append(std::to_string(uid.outside_id));
+               map.append(" ");
+               map.append(std::to_string(uid.count));
+               map.append("\n");
+       }
+       if (map.empty()) {
                return true;
        }
 
-       LOG_D("Writing '%s' to '%s'", map, fname);
-       if (!util::writeBufToFile(fname, map, strlen(map), O_WRONLY | O_CLOEXEC)) {
-               LOG_E("util::writeBufToFile('%s', '%s') failed", fname, map);
+       char fname[PATH_MAX];
+       snprintf(fname, sizeof(fname), "/proc/%d/uid_map", pid);
+       LOG_D("Writing '%s' to '%s'", map.c_str(), fname);
+       if (!util::writeBufToFile(fname, map.data(), map.length(), O_WRONLY | O_CLOEXEC)) {
+               LOG_E("util::writeBufToFile('%s', '%s') failed", fname, map.c_str());
                return false;
        }
 
@@ -124,26 +125,27 @@ static bool uidMapSelf(nsjconf_t* nsjconf, pid_t pid) {
 }
 
 static bool gidMapSelf(nsjconf_t* nsjconf, pid_t pid) {
-       char fname[PATH_MAX];
-       snprintf(fname, sizeof(fname), "/proc/%d/gid_map", pid);
-
-       char map[4096] = {[0] = '\0'};
-
+       std::string map;
        for (const auto& gid : nsjconf->gids) {
                if (gid.is_newidmap) {
                        continue;
                }
-               util::sSnPrintf(map, sizeof(map), "%lu %lu %zu\n", (unsigned long)gid.inside_id,
-                   (unsigned long)gid.outside_id, gid.count);
-       }
-
-       if (strlen(map) == 0) {
+               map.append(std::to_string(gid.inside_id));
+               map.append(" ");
+               map.append(std::to_string(gid.outside_id));
+               map.append(" ");
+               map.append(std::to_string(gid.count));
+               map.append("\n");
+       }
+       if (map.empty()) {
                return true;
        }
 
-       LOG_D("Writing '%s' to '%s'", map, fname);
-       if (!util::writeBufToFile(fname, map, strlen(map), O_WRONLY | O_CLOEXEC)) {
-               LOG_E("util::writeBufToFile('%s', '%s') failed", fname, map);
+       char fname[PATH_MAX];
+       snprintf(fname, sizeof(fname), "/proc/%d/gid_map", pid);
+       LOG_D("Writing '%s' to '%s'", map.c_str(), fname);
+       if (!util::writeBufToFile(fname, map.data(), map.length(), O_WRONLY | O_CLOEXEC)) {
+               LOG_E("util::writeBufToFile('%s', '%s') failed", fname, map.c_str());
                return false;
        }
 
@@ -152,47 +154,22 @@ static bool gidMapSelf(nsjconf_t* nsjconf, pid_t pid) {
 
 /* Use /usr/bin/newgidmap for writing the gid map */
 static bool gidMapExternal(nsjconf_t* nsjconf, pid_t pid UNUSED) {
-       size_t idx = 0;
-
-       const char* argv[1024];
-       char parms[1024][256];
-
-       argv[idx++] = "/usr/bin/newgidmap";
-
-       snprintf(parms[idx], sizeof(parms[idx]), "%u", (unsigned)pid);
-       argv[idx] = parms[idx];
-       idx++;
-
        bool use = false;
+
+       std::vector<std::string> argv = { "/usr/bin/newgidmap", std::to_string(pid) };
        for (const auto& gid : nsjconf->gids) {
-               if (gid.is_newidmap == false) {
+               if (!gid.is_newidmap) {
                        continue;
                }
-               if ((idx + 4) >= ARRAYSIZE(argv)) {
-                       LOG_W("Too many arguments for '/usr/bin/newgidmap'");
-                       return false;
-               }
                use = true;
 
-               snprintf(parms[idx], sizeof(parms[idx]), "%u", (unsigned)gid.inside_id);
-               argv[idx] = parms[idx];
-               idx++;
-
-               snprintf(parms[idx], sizeof(parms[idx]), "%u", (unsigned)gid.outside_id);
-               argv[idx] = parms[idx];
-               idx++;
-
-               snprintf(parms[idx], sizeof(parms[idx]), "%zu", gid.count);
-               argv[idx] = parms[idx];
-               idx++;
+               argv.push_back(std::to_string(gid.inside_id));
+               argv.push_back(std::to_string(gid.outside_id));
+               argv.push_back(std::to_string(gid.count));
        }
-
-       argv[idx] = NULL;
-
        if (!use) {
                return true;
        }
-
        if (subproc::systemExe(argv, environ) != 0) {
                LOG_E("'/usr/bin/newgidmap' failed");
                return false;
@@ -203,47 +180,22 @@ static bool gidMapExternal(nsjconf_t* nsjconf, pid_t pid UNUSED) {
 
 /* Use /usr/bin/newuidmap for writing the uid map */
 static bool uidMapExternal(nsjconf_t* nsjconf, pid_t pid UNUSED) {
-       size_t idx = 0;
-
-       const char* argv[1024];
-       char parms[1024][256];
-
-       argv[idx++] = "/usr/bin/newuidmap";
-
-       snprintf(parms[idx], sizeof(parms[idx]), "%u", (unsigned)pid);
-       argv[idx] = parms[idx];
-       idx++;
-
        bool use = false;
+
+       std::vector<std::string> argv = { "/usr/bin/newuidmap", std::to_string(pid) };
        for (const auto& uid : nsjconf->uids) {
-               if (uid.is_newidmap == false) {
+               if (!uid.is_newidmap) {
                        continue;
                }
-               if ((idx + 4) >= ARRAYSIZE(argv)) {
-                       LOG_W("Too many arguments for '/usr/bin/newuidmap'");
-                       return false;
-               }
                use = true;
 
-               snprintf(parms[idx], sizeof(parms[idx]), "%u", (unsigned)uid.inside_id);
-               argv[idx] = parms[idx];
-               idx++;
-
-               snprintf(parms[idx], sizeof(parms[idx]), "%u", (unsigned)uid.outside_id);
-               argv[idx] = parms[idx];
-               idx++;
-
-               snprintf(parms[idx], sizeof(parms[idx]), "%zu", uid.count);
-               argv[idx] = parms[idx];
-               idx++;
+               argv.push_back(std::to_string(uid.inside_id));
+               argv.push_back(std::to_string(uid.outside_id));
+               argv.push_back(std::to_string(uid.count));
        }
-
-       argv[idx] = NULL;
-
        if (!use) {
                return true;
        }
-
        if (subproc::systemExe(argv, environ) != 0) {
                LOG_E("'/usr/bin/newuidmap' failed");
                return false;