about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWill Dietz <w@wdtz.org>2018-03-01T21·00-0600
committerWill Dietz <w@wdtz.org>2018-03-02T16·52-0600
commitc89a3d536891da84403b025c70f1ae225faa0eb2 (patch)
treec019b3b8ead8a0c609d9a54db70e27904811863e
parent3748a0ca1e9406ff4a701b4f0e1f506c008c4137 (diff)
don't allocate large buffers on the stack
-rw-r--r--src/libstore/build.cc6
-rw-r--r--src/libutil/archive.cc18
-rw-r--r--src/libutil/hash.cc6
-rw-r--r--src/libutil/util.cc23
-rw-r--r--src/nix-daemon/nix-daemon.cc6
5 files changed, 30 insertions, 29 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 1d611ffbaba5..b33649e6b4a5 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -4156,8 +4156,8 @@ void Worker::waitForInput()
         set<int> fds2(j->fds);
         for (auto & k : fds2) {
             if (FD_ISSET(k, &fds)) {
-                unsigned char buffer[4096];
-                ssize_t rd = read(k, buffer, sizeof(buffer));
+                std::vector<unsigned char> buffer(4096);
+                ssize_t rd = read(k, buffer.data(), buffer.size());
                 if (rd == -1) {
                     if (errno != EINTR)
                         throw SysError(format("reading from %1%")
@@ -4169,7 +4169,7 @@ void Worker::waitForInput()
                 } else {
                     printMsg(lvlVomit, format("%1%: read %2% bytes")
                         % goal->getName() % rd);
-                    string data((char *) buffer, rd);
+                    string data((char *) buffer.data(), rd);
                     j->lastOutput = after;
                     goal->handleChildOutput(k, data);
                 }
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index f71229d8fdd6..59be91c5cfb8 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -40,14 +40,14 @@ static void dumpContents(const Path & path, size_t size,
     AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
     if (!fd) throw SysError(format("opening file '%1%'") % path);
 
-    unsigned char buf[65536];
+    std::vector<unsigned char> buf(65536);
     size_t left = size;
 
     while (left > 0) {
-        size_t n = left > sizeof(buf) ? sizeof(buf) : left;
-        readFull(fd.get(), buf, n);
+        size_t n = left > buf.size() ? buf.size() : left;
+        readFull(fd.get(), buf.data(), n);
         left -= n;
-        sink(buf, n);
+        sink(buf.data(), n);
     }
 
     writePadding(size, sink);
@@ -146,14 +146,14 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path)
     sink.preallocateContents(size);
 
     unsigned long long left = size;
-    unsigned char buf[65536];
+    std::vector<unsigned char> buf(65536);
 
     while (left) {
         checkInterrupt();
-        unsigned int n = sizeof(buf);
-        if ((unsigned long long) n > left) n = left;
-        source(buf, n);
-        sink.receiveContents(buf, n);
+        auto n = buf.size();
+        if ((unsigned long long)n > left) n = left;
+        source(buf.data(), n);
+        sink.receiveContents(buf.data(), n);
         left -= n;
     }
 
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index 75e4767550f7..8267481b8829 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -256,12 +256,12 @@ Hash hashFile(HashType ht, const Path & path)
     AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
     if (!fd) throw SysError(format("opening file '%1%'") % path);
 
-    unsigned char buf[8192];
+    std::vector<unsigned char> buf(8192);
     ssize_t n;
-    while ((n = read(fd.get(), buf, sizeof(buf)))) {
+    while ((n = read(fd.get(), buf.data(), buf.size()))) {
         checkInterrupt();
         if (n == -1) throw SysError(format("reading file '%1%'") % path);
-        update(ht, ctx, buf, n);
+        update(ht, ctx, buf.data(), n);
     }
 
     finish(ht, ctx, hash.hash);
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 2391e14a94bd..2c4705f6ba77 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -229,16 +229,17 @@ bool pathExists(const Path & path)
 Path readLink(const Path & path)
 {
     checkInterrupt();
+    std::vector<char> buf;
     for (ssize_t bufSize = PATH_MAX/4; true; bufSize += bufSize/2) {
-        char buf[bufSize];
-        ssize_t rlSize = readlink(path.c_str(), buf, bufSize);
+        buf.resize(bufSize);
+        ssize_t rlSize = readlink(path.c_str(), buf.data(), bufSize);
         if (rlSize == -1)
             if (errno == EINVAL)
                 throw Error("'%1%' is not a symlink", path);
             else
                 throw SysError("reading symbolic link '%1%'", path);
         else if (rlSize < bufSize)
-            return string(buf, rlSize);
+            return string(buf.data(), rlSize);
     }
 }
 
@@ -293,10 +294,10 @@ string readFile(int fd)
     if (fstat(fd, &st) == -1)
         throw SysError("statting file");
 
-    auto buf = std::make_unique<unsigned char[]>(st.st_size);
-    readFull(fd, buf.get(), st.st_size);
+    std::vector<unsigned char> buf(st.st_size);
+    readFull(fd, buf.data(), st.st_size);
 
-    return string((char *) buf.get(), st.st_size);
+    return string((char *) buf.data(), st.st_size);
 }
 
 
@@ -438,10 +439,10 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
 static Lazy<Path> getHome2([]() {
     Path homeDir = getEnv("HOME");
     if (homeDir.empty()) {
-        char buf[16384];
+        std::vector<char> buf(16384);
         struct passwd pwbuf;
         struct passwd * pw;
-        if (getpwuid_r(getuid(), &pwbuf, buf, sizeof(buf), &pw) != 0
+        if (getpwuid_r(getuid(), &pwbuf, buf.data(), buf.size(), &pw) != 0
             || !pw || !pw->pw_dir || !pw->pw_dir[0])
             throw Error("cannot determine user's home directory");
         homeDir = pw->pw_dir;
@@ -569,16 +570,16 @@ void writeFull(int fd, const string & s, bool allowInterrupts)
 string drainFD(int fd)
 {
     string result;
-    unsigned char buffer[4096];
+    std::vector<unsigned char> buffer(4096);
     while (1) {
         checkInterrupt();
-        ssize_t rd = read(fd, buffer, sizeof buffer);
+        ssize_t rd = read(fd, buffer.data(), buffer.size());
         if (rd == -1) {
             if (errno != EINTR)
                 throw SysError("reading from file");
         }
         else if (rd == 0) break;
-        else result.append((char *) buffer, rd);
+        else result.append((char *) buffer.data(), rd);
     }
     return result;
 }
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index 890bffa19aa5..c3b94614a879 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -37,13 +37,13 @@ using namespace nix;
 static ssize_t splice(int fd_in, void *off_in, int fd_out, void *off_out, size_t len, unsigned int flags)
 {
     /* We ignore most parameters, we just have them for conformance with the linux syscall */
-    char buf[8192];
-    auto read_count = read(fd_in, buf, sizeof(buf));
+    std::vector<char> buf(8192);
+    auto read_count = read(fd_in, buf.data(), buf.size());
     if (read_count == -1)
         return read_count;
     auto write_count = decltype(read_count)(0);
     while (write_count < read_count) {
-        auto res = write(fd_out, buf + write_count, read_count - write_count);
+        auto res = write(fd_out, buf.data() + write_count, read_count - write_count);
         if (res == -1)
             return res;
         write_count += res;