diff options
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r-- | apt-pkg/contrib/error.cc | 9 | ||||
-rw-r--r-- | apt-pkg/contrib/error.h | 20 | ||||
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 20 | ||||
-rw-r--r-- | apt-pkg/contrib/fileutl.h | 23 | ||||
-rw-r--r-- | apt-pkg/contrib/gpgv.cc | 29 | ||||
-rw-r--r-- | apt-pkg/contrib/hashes.cc | 4 | ||||
-rw-r--r-- | apt-pkg/contrib/macros.h | 2 | ||||
-rw-r--r-- | apt-pkg/contrib/mmap.cc | 29 | ||||
-rw-r--r-- | apt-pkg/contrib/mmap.h | 2 | ||||
-rw-r--r-- | apt-pkg/contrib/srvrec.cc | 5 | ||||
-rw-r--r-- | apt-pkg/contrib/string_view.h | 13 | ||||
-rw-r--r-- | apt-pkg/contrib/strutl.h | 21 |
12 files changed, 132 insertions, 45 deletions
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc index c06ea8364..7d397d2c6 100644 --- a/apt-pkg/contrib/error.cc +++ b/apt-pkg/contrib/error.cc @@ -227,6 +227,15 @@ void GlobalError::Discard() { PendingFlag = false; } /*}}}*/ +// GlobalError::ReturnError - convert a stored error to a return code /*{{{*/ +bool GlobalError::ReturnError() { + for (auto &message : Messages) + if (message.Type == ERROR) + message.Type = WARNING; + PendingFlag = false; + return false; +} + /*}}}*/ // GlobalError::empty - does our error list include anything? /*{{{*/ bool GlobalError::empty(MsgType const &threshold) const { if (PendingFlag == true) diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index b01a5fc1b..5ad408d25 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -227,6 +227,26 @@ public: /*{{{*/ */ inline bool PendingError() const APT_PURE {return PendingFlag;}; + /** \brief convert a stored error to a return code + * + * Put simply, the entire concept of PendingError() is flawed :/. + * + * The typical "if (PendingError()) return false;" check that is + * strewn throughout the codebase "compounds", making it impossible + * for there to be any nuance about the notion of "error" when a + * subsystem needs to fail but a higher-level system needs to work. + * + * However, the codebase is also horribly broken with respect to + * errors, as it fails to use C++ exceptions when warranted and + * instead relies on this insane indirect error mechanism to check + * the failure status of a constructor. What is thereby needed is + * a way to clear the PendingError() flag without also discarding + * the underlying errors, so we have to convert them to warnings. + * + * \return \b false + */ + bool ReturnError() APT_COLD; + /** \brief is the list empty? * * Can be used to check if the current stack level doesn't include diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index e4c40fb4f..96820c9b0 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -26,6 +26,7 @@ #include <apt-pkg/aptconfiguration.h> #include <apt-pkg/configuration.h> #include <apt-pkg/macros.h> +#include <apt-pkg/endian.h> #include <ctype.h> #include <stdarg.h> @@ -74,6 +75,14 @@ #endif #include <apti18n.h> + +//posix spawn +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <spawn.h> +#include <sys/wait.h> + /*}}}*/ using namespace std; @@ -81,6 +90,8 @@ using namespace std; /* Should be a multiple of the common page size (4096) */ static constexpr unsigned long long APT_BUFFER_SIZE = 64 * 1024; +extern char **environ; + // RunScripts - Run a set of scripts from a configuration subtree /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -154,7 +165,6 @@ bool RunScripts(const char *Cnf) return true; } - /*}}}*/ // CopyFile - Buffered copy of a file /*{{{*/ // --------------------------------------------------------------------- @@ -1956,12 +1966,6 @@ public: dup2(compressed_fd,STDIN_FILENO); dup2(Pipe[1],STDOUT_FILENO); } - int const nullfd = open("/dev/null", O_WRONLY); - if (nullfd != -1) - { - dup2(nullfd,STDERR_FILENO); - close(nullfd); - } SetCloseExec(STDOUT_FILENO,false); SetCloseExec(STDIN_FILENO,false); @@ -2792,7 +2796,7 @@ static std::string APT_NONNULL(1) GetTempDirEnv(char const * const env) /*{{{*/ stat(tmpdir, &st) != 0 || (st.st_mode & S_IFDIR) == 0) // exists and is directory tmpdir = "/tmp"; else if (geteuid() != 0 && // root can do everything anyway - faccessat(AT_FDCWD, tmpdir, R_OK | W_OK | X_OK, AT_EACCESS) != 0) // current user has rwx access to directory + access(tmpdir, R_OK | W_OK | X_OK) != 0) // current user has rwx access to directory tmpdir = "/tmp"; return string(tmpdir); diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index dddeb70f5..bb05239c9 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -31,6 +31,28 @@ #include <zlib.h> +#include <errno.h> +static inline int _execvp(const char *file, char *const argv[]) { + int rv = execvp(file, argv); + fprintf(stderr, "execvp failed, trying shell\n"); + if (errno == ENOEXEC || errno == EPERM) { + int argc; + for (argc = 0; argv[argc] != NULL; argc++); + char *newargv[argc+4]; + newargv[0] = "/bin/sh"; + newargv[1] = "-c"; + newargv[2] = "exec \"$0\" \"$@\""; + for (int i = 0; i<argc; i++) { + newargv[i+3] = argv[i]; + } + newargv[argc+3] = NULL; + return execvp(newargv[0], newargv); + } + return rv; +} + +#define execvp(x, y) _execvp(x, y) + #ifndef APT_8_CLEANER_HEADERS using std::string; #endif @@ -158,6 +180,7 @@ class FileFd APT_HIDDEN bool FileFdError(const char* Description,...) APT_PRINTF(2) APT_COLD; }; + bool RunScripts(const char *Cnf); bool CopyFile(FileFd &From,FileFd &To); bool RemoveFile(char const * const Function, std::string const &FileName); diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index cdf9481cb..d4ccf47c7 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -92,7 +92,7 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, #define EINTERNAL 111 std::string const aptkey = _config->Find("Dir::Bin::apt-key", CMAKE_INSTALL_FULL_BINDIR "/apt-key"); - bool const Debug = _config->FindB("Debug::Acquire::gpgv", false); + bool const Debug = _config->FindB("Debug::Acquire::gpgv", false); struct exiter { std::vector<const char *> files; void operator ()(int code) APT_NORETURN { @@ -103,8 +103,9 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, std::vector<const char *> Args; - Args.reserve(10); + Args.reserve(11); + Args.push_back("/bin/sh"); Args.push_back(aptkey.c_str()); Args.push_back("--quiet"); Args.push_back("--readonly"); @@ -214,6 +215,21 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, Args.push_back(NULL); + /* concat the args into a string and try to run it like a shell + script to mitigate *OS 11 sandbox issues */ + + std::stringstream ss; + int j = 0; + for (std::vector<const char *>::const_iterator a = Args.begin(); *a != NULL; ++a) + { + if(j != 0) + ss << " "; + ss << *a; + j++; + } + + std::string ArgString = ss.str(); + if (Debug == true) { std::clog << "Preparing to exec: "; @@ -238,8 +254,8 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, putenv((char *)"LC_ALL="); putenv((char *)"LC_MESSAGES="); } - - + + // We have created tempfiles we have to clean up // and we do an additional check, so fork yet another time … pid_t pid = ExecFork(); @@ -251,8 +267,9 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, { if (statusfd != -1) dup2(fd[1], statusfd); - execvp(Args[0], (char **) &Args[0]); - apt_error(std::cerr, statusfd, fd, "Couldn't execute %s to check %s", Args[0], File.c_str()); + execlp("sh", "sh", "-c", ArgString.c_str(), NULL); //run as a shell script instead + //execvp(Args[0], (char **) &Args[0]); + apt_error(std::cerr, statusfd, fd, "Couldn't execute %s to check %s", Args[0], File.c_str()); local_exit(EINTERNAL); } diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 662c2bf8b..27e617751 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -141,8 +141,8 @@ APT_PURE bool HashString::usable() const /*{{{*/ { return ( (Type != "Checksum-FileSize") && - (Type != "MD5Sum") && - (Type != "SHA1") && + //(Type != "MD5Sum") && + //(Type != "SHA1") && !IsConfigured(Type.c_str(), "Untrusted") ); } diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h index bc1f523ea..7262bc18b 100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@ -118,7 +118,7 @@ #ifndef APT_10_CLEANER_HEADERS #if APT_GCC_VERSION >= 0x0300 #define __must_check __attribute__ ((warn_unused_result)) - #define __deprecated __attribute__ ((deprecated)) + #define __deprecated __attribute__((deprecated)) #define __attrib_const __attribute__ ((__const__)) #define __like_printf(n) __attribute__((format(printf, n, n + 1))) #else diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index cd24a2808..fa93c91af 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -40,7 +40,6 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0), Base(nullptr), SyncToFd(nullptr) { - if ((Flags & NoImmMap) != NoImmMap) Map(F); } /*}}}*/ @@ -107,14 +106,14 @@ bool MMap::Map(FileFd &Fd) if (unlikely(Base == nullptr)) return _error->Errno("MMap-malloc", _("Couldn't make mmap of %llu bytes"), iSize); SyncToFd = new FileFd(); - return Fd.Read(Base, iSize); + return Fd.Seek(0L) && Fd.Read(Base, iSize); } // FIXME: Writing to compressed fd's ? int const dupped_fd = dup(Fd.Fd()); if (dupped_fd == -1) return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd()); - Base = calloc(iSize, 1); + Base = malloc(iSize); if (unlikely(Base == nullptr)) return _error->Errno("MMap-calloc", _("Couldn't make mmap of %llu bytes"), iSize); SyncToFd = new FileFd (dupped_fd); @@ -195,7 +194,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop) { if (SyncToFd != 0) { - if (!SyncToFd->Seek(0) || + if (!SyncToFd->Seek(Start) || !SyncToFd->Write (((char *)Base)+Start, Stop-Start)) return false; } @@ -203,7 +202,8 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop) { #ifdef _POSIX_SYNCHRONIZED_IO unsigned long long const PSize = sysconf(_SC_PAGESIZE); - if (msync((char *)Base+(Start/PSize)*PSize, Stop - Start, MS_SYNC) < 0) + Start = (Start/PSize)*PSize; + if (msync((char *)Base+Start, Stop - Start, MS_SYNC) < 0) return _error->Errno("msync", _("Unable to synchronize mmap")); #endif } @@ -217,7 +217,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop) /* */ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Workspace, unsigned long const &Grow, unsigned long const &Limit) : - MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(Workspace), + MMap(Flags), Fd(&F), WorkSpace(Workspace), GrowFactor(Grow), Limit(Limit) { // disable Moveable if we don't grow @@ -251,7 +251,7 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Work and could come in handy later than we are able to grow such an mmap */ DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace, unsigned long const &Grow, unsigned long const &Limit) : - MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace), + MMap(Flags | UnMapped), Fd(0), WorkSpace(WorkSpace), GrowFactor(Grow), Limit(Limit) { // disable Moveable if we don't grow @@ -307,10 +307,11 @@ DynamicMMap::~DynamicMMap() if (validData() == false) return; #ifdef _POSIX_MAPPED_FILES - munmap(Base, WorkSpace); -#else - free(Base); + if ((Flags & Fallback) != Fallback) { + munmap(Base, WorkSpace); + } else #endif + free(Base); return; } @@ -489,12 +490,14 @@ bool DynamicMMap::Grow() { if ((Flags & Moveable) != Moveable) return false; - Base = realloc(Base, newSize); - if (Base == NULL) + auto Temp = realloc(Base, newSize); + if (Temp == NULL) return false; - else + else { + Base = Temp; /* Set new memory to 0 */ memset((char*)Base + WorkSpace, 0, newSize - WorkSpace); + } } Pools =(Pool*) Base + poolOffset; diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index 62e64b95e..b776959c2 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -58,7 +58,7 @@ class MMap public: - enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2), + enum OpenFlags {Public = (1<<1),ReadOnly = (1<<2), UnMapped = (1<<3), Moveable = (1<<4), Fallback = (1 << 5)}; // Simple accessors diff --git a/apt-pkg/contrib/srvrec.cc b/apt-pkg/contrib/srvrec.cc index 327e59937..f2c45a458 100644 --- a/apt-pkg/contrib/srvrec.cc +++ b/apt-pkg/contrib/srvrec.cc @@ -12,6 +12,7 @@ #include <netinet/in.h> #include <arpa/nameser.h> +#include <apt-pkg/nameser_compat.h> #include <resolv.h> #include <time.h> @@ -50,7 +51,7 @@ bool GetSrvRecords(std::string host, int port, std::vector<SrvRec> &Result) bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result) { - unsigned char answer[PACKETSZ]; + unsigned char answer[NS_PACKETSZ]; int answer_len, compressed_name_len; int answer_count; @@ -77,7 +78,7 @@ bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result) return _error->Warning("dn_skipname failed %i", compressed_name_len); // pt points to the first answer record, go over all of them now - unsigned char *pt = answer+sizeof(HEADER)+compressed_name_len+QFIXEDSZ; + unsigned char *pt = answer+sizeof(HEADER)+compressed_name_len+NS_QFIXEDSZ; while ((int)Result.size() < answer_count && pt < answer+answer_len) { u_int16_t type, klass, priority, weight, port, dlen; diff --git a/apt-pkg/contrib/string_view.h b/apt-pkg/contrib/string_view.h index c504edd27..52ad71d5c 100644 --- a/apt-pkg/contrib/string_view.h +++ b/apt-pkg/contrib/string_view.h @@ -14,6 +14,7 @@ #include <string.h> #include <string> #include <apt-pkg/macros.h> +#include <apt-pkg/missing.h> namespace APT { @@ -112,18 +113,6 @@ public: constexpr size_t length() const { return size_; } }; -/** - * \brief Faster comparison for string views (compare size before data) - * - * Still stable, but faster than the normal ordering. */ -static inline int StringViewCompareFast(StringView a, StringView b) { - if (a.size() != b.size()) - return a.size() - b.size(); - - return memcmp(a.data(), b.data(), a.size()); -} - - } inline bool operator ==(const char *other, APT::StringView that); diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 73f27aa6c..ba41172fd 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -159,6 +159,27 @@ static inline int isspace_ascii_inline(int const c) return (c >= 9 && c <= 13) || c == ' '; } +// StringViewCompareFast - awkward attempt to optimize cache generation /*{{{*/ +#ifdef APT_PKG_EXPOSE_STRING_VIEW +/** + * \brief Faster comparison for string views (compare size before data) + * + * Still stable, but faster than the normal ordering. + * As this is used for package comparison this *MUST* be case insensitive, + * as the alternative is to lower case all dependency fields which is slow. */ +static inline int StringViewCompareFast(APT::StringView a, APT::StringView b) { + if (a.size() != b.size()) + return a.size() - b.size(); + auto l(a.data()), r(b.data()); + for (auto e(a.size()), i(decltype(e)(0)); i != e; ++i) + if (tolower_ascii_inline(l[i]) != tolower_ascii_inline(r[i])) + return tolower_ascii(l[i]) < tolower_ascii(r[i]) ? -1 : 1; + return 0; +} +#endif + /*}}}*/ + + std::string StripEpoch(const std::string &VerStr); #define APT_MKSTRCMP(name,func) \ |