]> git.saurik.com Git - apt.git/commitdiff
don't leak an FD in lz4 (de)compression
authorDavid Kalnischkies <david@kalnischkies.de>
Thu, 9 Jun 2016 19:06:48 +0000 (21:06 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Fri, 10 Jun 2016 08:49:34 +0000 (10:49 +0200)
Seen first in #826783, but as this buglog also shows leaked uncompressed
files as well we don't close it just yet.

apt-pkg/contrib/fileutl.cc
test/integration/test-apt-helper-cat-file
test/interactive-helper/makefile
test/interactive-helper/test_fileutl.cc [new file with mode: 0644]
test/libapt/file-helpers.cc

index 6bfa5ca9285ffd7ff2e572c682930531efed16ca..94d1432cfa908bc14261ea5f08b48f45bfcccd47 100644 (file)
@@ -1535,7 +1535,7 @@ public:
         return false;
 
       unsigned int flags = (Mode & (FileFd::WriteOnly|FileFd::ReadOnly));
         return false;
 
       unsigned int flags = (Mode & (FileFd::WriteOnly|FileFd::ReadOnly));
-      if (backend.OpenDescriptor(iFd, flags) == false)
+      if (backend.OpenDescriptor(iFd, flags, FileFd::None, true) == false)
         return false;
 
       // Write the file header
         return false;
 
       // Write the file header
@@ -1646,6 +1646,11 @@ public:
         res = LZ4F_freeDecompressionContext(dctx);
         dctx = nullptr;
       }
         res = LZ4F_freeDecompressionContext(dctx);
         dctx = nullptr;
       }
+      if (backend.IsOpen())
+      {
+        backend.Close();
+        filefd->iFd = -1;
+      }
 
       return LZ4F_isError(res) == false;
    }
 
       return LZ4F_isError(res) == false;
    }
index f7c94a2b4e237b1f1fa9d1906bdb9977188d6b47..3f509189ec2acc9c9ef9a232cf9257734b1ac3e2 100755 (executable)
@@ -5,6 +5,15 @@ TESTDIR="$(readlink -f "$(dirname "$0")")"
 . "$TESTDIR/framework"
 setupenvironment
 
 . "$TESTDIR/framework"
 setupenvironment
 
+TESTTOOL="${BUILDDIRECTORY}/test_fileutl"
+msgtest 'Check if we have build the test tool' "$TESTTOOL"
+if [ -x "$TESTTOOL" ]; then
+       msgpass
+else
+       msgskip 'not available'
+       exit 0
+fi
+
 cat >rootdir/etc/apt/apt.conf.d/rev-as-compressor <<EOF
 APT::Compressor::rev {
        Name "rev";
 cat >rootdir/etc/apt/apt.conf.d/rev-as-compressor <<EOF
 APT::Compressor::rev {
        Name "rev";
@@ -26,5 +35,12 @@ while read compressor extension command; do
        else
                FILE="./test.txt.${extension}"
        fi
        else
                FILE="./test.txt.${extension}"
        fi
+       if [ -d /proc/self/fd ]; then
+               testsuccess runapt "${TESTTOOL}" "$FILE"
+               testequal '3' grep -c '/test.txt' rootdir/tmp/testsuccess.output
+       else
+               msgtest 'Test if /proc interface is available'
+               msgskip 'seems not'
+       fi
        testsuccessequal "$(cat ./test.txt)" apthelper cat-file "$FILE"
 done < "${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf"
        testsuccessequal "$(cat ./test.txt)" apthelper cat-file "$FILE"
 done < "${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf"
index 4633b78ce66bd33c87d589c001d1a4df6a55aa99..096767c414780fc8df4c5a4435febe9e02f46bb2 100644 (file)
@@ -33,6 +33,12 @@ LIB_MAKES = apt-pkg/makefile
 SOURCE = test_udevcdrom.cc
 include $(PROGRAM_H)
 
 SOURCE = test_udevcdrom.cc
 include $(PROGRAM_H)
 
+PROGRAM=test_fileutl
+SLIBS = -lapt-pkg
+LIB_MAKES = apt-pkg/makefile
+SOURCE = test_fileutl.cc
+include $(PROGRAM_H)
+
 # Program for checking rpm versions
 #PROGRAM=rpmver
 #SLIBS = -lapt-pkg -lrpm
 # Program for checking rpm versions
 #PROGRAM=rpmver
 #SLIBS = -lapt-pkg -lrpm
diff --git a/test/interactive-helper/test_fileutl.cc b/test/interactive-helper/test_fileutl.cc
new file mode 100644 (file)
index 0000000..e660c29
--- /dev/null
@@ -0,0 +1,43 @@
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/error.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <iostream>
+#include <string>
+
+static void callsystem(std::string const &call)
+{
+   auto ret = system(call.c_str());
+   if (WIFEXITED(ret) == false || WEXITSTATUS(ret) != 0)
+      _error->Error("Calling %s failed!", call.c_str());
+}
+
+int main(int, char ** argv)
+{
+       auto const pid = getpid();
+       std::string ls;
+       strprintf(ls, "ls -l /proc/%d/fd", pid);
+       callsystem(ls);
+       FileFd t;
+       t.Open(argv[1], FileFd::ReadOnly, FileFd::Extension);
+       callsystem(ls);
+       char buf[1024];
+       unsigned long long act;
+       while (t.Read(buf, sizeof(buf), &act))
+               if (act == 0)
+                       break;
+       callsystem(ls);
+       t.Seek(5);
+       callsystem(ls);
+       t.Close();
+       callsystem(ls);
+       auto const ret = _error->PendingError();
+       _error->DumpErrors();
+       return ret;
+}
index 6811c4158661f6f4f5d711193ff0e95868ca7137..48d8a9fbbf9a25a2a226f4ae888de32622d24212 100644 (file)
@@ -74,7 +74,7 @@ void helperCreateTemporaryFile(std::string const &id, FileFd &fd, std::string *
       unlink(tempfile);
    free(tempfile);
 
       unlink(tempfile);
    free(tempfile);
 
-   EXPECT_TRUE(fd.OpenDescriptor(tempfile_fd, FileFd::ReadWrite));
+   EXPECT_TRUE(fd.OpenDescriptor(tempfile_fd, FileFd::ReadWrite, true));
    if (content != NULL)
    {
       ASSERT_TRUE(fd.Write(content, strlen(content)));
    if (content != NULL)
    {
       ASSERT_TRUE(fd.Write(content, strlen(content)));