summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/error.cc9
-rw-r--r--apt-pkg/contrib/error.h20
-rw-r--r--apt-pkg/contrib/fileutl.cc171
-rw-r--r--apt-pkg/contrib/fileutl.h2
-rw-r--r--apt-pkg/contrib/gpgv.cc29
-rw-r--r--apt-pkg/contrib/hashes.cc4
-rw-r--r--apt-pkg/contrib/macros.h2
-rw-r--r--apt-pkg/contrib/mmap.cc29
-rw-r--r--apt-pkg/contrib/mmap.h2
-rw-r--r--apt-pkg/contrib/srvrec.cc5
-rw-r--r--apt-pkg/contrib/string_view.h13
-rw-r--r--apt-pkg/contrib/strutl.h21
12 files changed, 263 insertions, 44 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..a90cd647a 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 /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -119,7 +130,7 @@ bool RunScripts(const char *Cnf)
std::clog << "Running external script: '"
<< Opts->Value << "'" << std::endl;
- if (system(Opts->Value.c_str()) != 0)
+ if (RunCmd(Opts->Value.c_str()) != 0)
_exit(100+Count);
}
_exit(0);
@@ -154,6 +165,158 @@ bool RunScripts(const char *Cnf)
return true;
}
+
+#define PROC_PIDPATHINFO_MAXSIZE (1024)
+static int file_exist(const char *filename) {
+ struct stat buffer;
+ int r = stat(filename, &buffer);
+ return (r == 0);
+}
+
+static char *searchpath(const char *binaryname){
+ if (strstr(binaryname, "/") != NULL){
+ if (file_exist(binaryname)){
+ char *foundpath = (char *)malloc((strlen(binaryname) + 1) * (sizeof(char)));
+ strcpy(foundpath, binaryname);
+ return foundpath;
+ } else {
+ return NULL;
+ }
+ }
+
+ char *pathvar = getenv("PATH");
+
+ char *dir = strtok(pathvar,":");
+ while (dir != NULL){
+ char searchpth[PROC_PIDPATHINFO_MAXSIZE];
+ strcpy(searchpth, dir);
+ strcat(searchpth, "/");
+ strcat(searchpth, binaryname);
+
+ if (file_exist(searchpth)){
+ char *foundpath = (char *)malloc((strlen(searchpth) + 1) * (sizeof(char)));
+ strcpy(foundpath, searchpth);
+ return foundpath;
+ }
+
+ dir = strtok(NULL, ":");
+ }
+ return NULL;
+}
+
+static bool isShellScript(const char *path){
+ FILE *file = fopen(path, "r");
+ uint8_t header[2];
+ if (fread(header, sizeof(uint8_t), 2, file) == 2){
+ if (header[0] == '#' && header[1] == '!'){
+ fclose(file);
+ return true;
+ }
+ }
+ fclose(file);
+ return false;
+}
+
+static char *getInterpreter(char *path){
+ FILE *file = fopen(path, "r");
+ char *interpreterLine = NULL;
+ unsigned long lineSize = 0;
+ getline(&interpreterLine, &lineSize, file);
+
+ char *rawInterpreter = (interpreterLine+2);
+ rawInterpreter = strtok(rawInterpreter, " ");
+ rawInterpreter = strtok(rawInterpreter, "\n");
+
+ char *interpreter = (char *)malloc((strlen(rawInterpreter)+1) * sizeof(char));
+ strcpy(interpreter, rawInterpreter);
+
+ free(interpreterLine);
+ fclose(file);
+ return interpreter;
+}
+
+static char *fixedCmd(const char *cmdStr){
+ char *cmdCpy = (char *)malloc((strlen(cmdStr)+1) * sizeof(char));
+ strcpy(cmdCpy, cmdStr);
+
+ char *cmd = strtok(cmdCpy, " ");
+
+ uint8_t size = strlen(cmd) + 1;
+
+ char *args = cmdCpy + size;
+ if ((strlen(cmdStr) - strlen(cmd)) == 0)
+ args = NULL;
+
+ char *abs_path = searchpath(cmd);
+ if (abs_path){
+ bool isScript = isShellScript(abs_path);
+ if (isScript){
+ char *interpreter = getInterpreter(abs_path);
+
+ uint8_t commandSize = strlen(interpreter) + 1 + strlen(abs_path);
+
+ if (args){
+ commandSize += 1 + strlen(args);
+ }
+
+ char *rawCommand = (char *)malloc(sizeof(char) * (commandSize + 1));
+ strcpy(rawCommand, interpreter);
+ strcat(rawCommand, " ");
+ strcat(rawCommand, abs_path);
+
+ if (args){
+ strcat(rawCommand, " ");
+ strcat(rawCommand, args);
+ }
+ rawCommand[(commandSize)+1] = '\0';
+
+ free(interpreter);
+ free(abs_path);
+ free(cmdCpy);
+
+ return rawCommand;
+ } else {
+ uint8_t commandSize = strlen(abs_path);
+
+ if (args){
+ commandSize += 1 + strlen(args);
+ }
+
+ char *rawCommand = (char *)malloc(sizeof(char) * (commandSize + 1));
+ strcat(rawCommand, abs_path);
+
+ if (args){
+ strcat(rawCommand, " ");
+ strcat(rawCommand, args);
+ }
+ rawCommand[(commandSize)+1] = '\0';
+
+ free(abs_path);
+ free(cmdCpy);
+
+ return rawCommand;
+ }
+ }
+ return cmdCpy;
+}
+
+int RunCmd(const char *cmd) {
+ pid_t pid;
+ char *rawCmd = fixedCmd(cmd);
+ char *argv[] = {"sh", "-c", (char*)rawCmd, NULL};
+ int status;
+ status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
+ if (status == 0) {
+ if (waitpid(pid, &status, 0) == -1) {
+ perror("waitpid");
+ }
+ } else {
+ printf("posix_spawn: %s\n", strerror(status));
+ }
+ free(rawCmd);
+ return status;
+}
+
/*}}}*/
// CopyFile - Buffered copy of a file /*{{{*/
@@ -1956,12 +2119,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);
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index dddeb70f5..932538206 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -158,6 +158,8 @@ class FileFd
APT_HIDDEN bool FileFdError(const char* Description,...) APT_PRINTF(2) APT_COLD;
};
+
+int RunCmd(const char *Cmd);
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) \