]> git.saurik.com Git - apt.git/commitdiff
Merge remote-tracking branch 'mvo/bugfix/lp1304657-perms' into debian/sid
authorMichael Vogt <mvo@ubuntu.com>
Thu, 10 Apr 2014 07:15:03 +0000 (09:15 +0200)
committerMichael Vogt <mvo@ubuntu.com>
Thu, 10 Apr 2014 07:15:03 +0000 (09:15 +0200)
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h
test/integration/framework
test/libapt/fileutl_test.cc

index 188bb87eebbcec1410299e07ab251d88a3af49ff..69a675648f2551a6b129dc201904a2069b666235 100644 (file)
@@ -958,10 +958,10 @@ class FileFdPrivate {                                                     /*{{{*/
 // FileFd::Open - Open a file                                          /*{{{*/
 // ---------------------------------------------------------------------
 /* The most commonly used open mode combinations are given with Mode */
-bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const Perms)
+bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const AccessMode)
 {
    if (Mode == ReadOnlyGzip)
-      return Open(FileName, ReadOnly, Gzip, Perms);
+      return Open(FileName, ReadOnly, Gzip, AccessMode);
 
    if (Compress == Auto && (Mode & WriteOnly) == WriteOnly)
       return FileFdError("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str());
@@ -1028,9 +1028,9 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress,
 
    if (compressor == compressors.end())
       return FileFdError("Can't find a match for specified compressor mode for file %s", FileName.c_str());
-   return Open(FileName, Mode, *compressor, Perms);
+   return Open(FileName, Mode, *compressor, AccessMode);
 }
-bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms)
+bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const AccessMode)
 {
    Close();
    Flags = AutoClose;
@@ -1067,6 +1067,13 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co
    if_FLAGGED_SET(Exclusive, O_EXCL);
    #undef if_FLAGGED_SET
 
+   // umask() will always set the umask and return the previous value, so
+   // we first set the umask and then reset it to the old value
+   mode_t CurrentUmask = umask(0);
+   umask(CurrentUmask);
+   // calculate the actual file permissions (just like open/creat)
+   mode_t FilePermissions = (AccessMode & ~CurrentUmask);
+
    if ((Mode & Atomic) == Atomic)
    {
       char *name = strdup((FileName + ".XXXXXX").c_str());
@@ -1080,11 +1087,11 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co
       TemporaryFileName = string(name);
       free(name);
 
-      if(Perms != 600 && fchmod(iFd, Perms) == -1)
+      if(FilePermissions != 600 && fchmod(iFd, FilePermissions) == -1)
           return FileFdErrno("fchmod", "Could not change permissions for temporary file %s", TemporaryFileName.c_str());
    }
    else
-      iFd = open(FileName.c_str(), fileflags, Perms);
+      iFd = open(FileName.c_str(), fileflags, FilePermissions);
 
    this->FileName = FileName;
    if (iFd == -1 || OpenInternDescriptor(Mode, compressor) == false)
index f25ed362206d7c7ae5dceba6af248a1c1333f9c3..cc1a98eae02c227b47962dff72421baf0e3f5e6d 100644 (file)
@@ -103,10 +103,10 @@ class FileFd
        return T;
    }
 
-   bool Open(std::string FileName,unsigned int const Mode,CompressMode Compress,unsigned long const Perms = 0666);
-   bool Open(std::string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor,unsigned long const Perms = 0666);
-   inline bool Open(std::string const &FileName,unsigned int const Mode, unsigned long const Perms = 0666) {
-      return Open(FileName, Mode, None, Perms);
+   bool Open(std::string FileName,unsigned int const Mode,CompressMode Compress,unsigned long const AccessMode = 0666);
+   bool Open(std::string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor,unsigned long const AccessMode = 0666);
+   inline bool Open(std::string const &FileName,unsigned int const Mode, unsigned long const AccessMode = 0666) {
+      return Open(FileName, Mode, None, AccessMode);
    };
    bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false);
    bool OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false);
@@ -129,13 +129,13 @@ class FileFd
    inline bool IsCompressed() {return (Flags & Compressed) == Compressed;};
    inline std::string &Name() {return FileName;};
    
-   FileFd(std::string FileName,unsigned int const Mode,unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
+   FileFd(std::string FileName,unsigned int const Mode,unsigned long AccessMode = 0666) : iFd(-1), Flags(0), d(NULL)
    {
-      Open(FileName,Mode, None, Perms);
+      Open(FileName,Mode, None, AccessMode);
    };
-   FileFd(std::string FileName,unsigned int const Mode, CompressMode Compress, unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
+   FileFd(std::string FileName,unsigned int const Mode, CompressMode Compress, unsigned long AccessMode = 0666) : iFd(-1), Flags(0), d(NULL)
    {
-      Open(FileName,Mode, Compress, Perms);
+      Open(FileName,Mode, Compress, AccessMode);
    };
    FileFd() : iFd(-1), Flags(AutoClose), d(NULL) {};
    FileFd(int const Fd, unsigned int const Mode = ReadWrite, CompressMode Compress = None) : iFd(-1), Flags(0), d(NULL)
index 1c6f041b0b3a8544648064721566c12bfbdc6f4d..8d8a0beccc50daac86e24de8dcb0e9e303cbba25 100644 (file)
@@ -879,6 +879,20 @@ rewritesourceslist() {
        done
 }
 
+# wait for up to 10s for a pid file to appear to avoid possible race
+# when a helper is started and dosn't write the PID quick enough
+waitforpidfile() {
+        local PIDFILE="$1"
+        for i in $(seq 10); do
+                if test -s "$PIDFILE"; then
+                        return 0
+                fi
+                sleep 1
+        done
+        msgdie "waiting for $PIDFILE failed"
+        return 1
+}
+
 changetowebserver() {
        if [ "$1" != '--no-rewrite' ]; then
                rewritesourceslist 'http://localhost:8080/'
@@ -892,6 +906,7 @@ changetowebserver() {
                        cat $LOG
                        false
                fi
+                waitforpidfile aptwebserver.pid
                local PID="$(cat aptwebserver.pid)"
                if [ -z "$PID" ]; then
                        msgdie 'Could not fork aptwebserver successfully'
@@ -919,7 +934,11 @@ accept = 4433
 connect = 8080
 " > ${TMPWORKINGDIRECTORY}/stunnel.conf
        stunnel4 "${TMPWORKINGDIRECTORY}/stunnel.conf"
+        waitforpidfile "${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid"
        local PID="$(cat ${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid)"
+        if [ -z "$PID" ]; then
+               msgdie 'Could not fork stunnel4 successfully'
+       fi
        addtrap 'prefix' "kill ${PID};"
        rewritesourceslist 'https://localhost:4433/'
 }
index 8da832ba9f3359f689f8c42f35446b4f0c577721..1d1a1a1b8ddcc39fd81b270ec549b0f3ffccf64e 100644 (file)
@@ -6,13 +6,44 @@
 #include <string>
 #include <vector>
 #include <stdlib.h>
+#include <sys/stat.h>
 
 #include "assert.h"
 
+// regression test for permission bug LP: #1304657
+static bool
+TestFileFdOpenPermissions(mode_t a_umask, mode_t ExpectedFilePermission)
+{
+   FileFd f;
+   struct stat buf;
+   static const char* fname = "test.txt";
+
+   umask(a_umask);
+   f.Open(fname, FileFd::ReadWrite|FileFd::Atomic);
+   f.Close();
+   if (stat(fname, &buf) < 0)
+   {
+      _error->Errno("stat", "failed to stat");
+      _error->DumpErrors();
+      return false;
+   }
+   unlink(fname);
+   equals(buf.st_mode & 0777, ExpectedFilePermission);
+   return true;
+}
+
 int main()
 {
    std::vector<std::string> files;
 
+   if (TestFileFdOpenPermissions(0002, 0664) == false ||
+       TestFileFdOpenPermissions(0022, 0644) == false ||
+       TestFileFdOpenPermissions(0077, 0600) == false ||
+       TestFileFdOpenPermissions(0026, 0640) == false)
+   {
+      return 1;
+   }
+
    // normal match
    files = Glob("*.lst");
    if (files.size() != 1)