]> git.saurik.com Git - apt.git/commitdiff
Do not parse Status fields from remote sources
authorJulian Andres Klode <jak@debian.org>
Fri, 21 Aug 2015 16:00:37 +0000 (18:00 +0200)
committerJulian Andres Klode <jak@debian.org>
Thu, 27 Aug 2015 12:51:47 +0000 (14:51 +0200)
This could allow an attacker to mark a package as installed in a
remote package index, as long as the package was not listed in
the dpkg status file.

This way, an attacker could force the installation of a package
during a dist-upgrade, by providing two packages in an index,
an older marked as installed, and a newer - apt would "upgrade"
to the newer version.

apt-pkg/deb/debindexfile.cc
apt-pkg/deb/debindexfile.h
apt-pkg/deb/deblistparser.cc
apt-pkg/deb/deblistparser.h
test/integration/test-security-no-remote-status [new file with mode: 0755]

index c43ee7b917426101cfffc3f4b15eeb151c23c3bc..32ccd75291fe212503d114e04958a3ef3d5f678a 100644 (file)
@@ -145,6 +145,17 @@ uint8_t debStatusIndex::GetIndexFlags() const
 {
    return pkgCache::Flag::NotSource;
 }
+
+pkgCacheListParser * debStatusIndex::CreateListParser(FileFd &Pkg)
+{
+   if (Pkg.IsOpen() == false)
+      return NULL;
+   _error->PushToStack();
+   pkgCacheListParser * const Parser = new debStatusListParser(&Pkg);
+   bool const newError = _error->PendingError();
+   _error->MergeWithStack();
+   return newError ? NULL : Parser;
+}
                                                                        /*}}}*/
 // DebPkgFile Index - a single .deb file as an index                   /*{{{*/
 debDebPkgFileIndex::debDebPkgFileIndex(std::string const &DebFile)
index dc75a01ab0544f81b75103db99739b9229856ab7..5bec4f2ea8b96ca66c0f1e48a1e8b6311c57a854 100644 (file)
@@ -43,6 +43,8 @@ public:
    // Abort if the file does not exist.
    virtual bool Exists() const APT_OVERRIDE {return true;};
 
+   virtual pkgCacheListParser * CreateListParser(FileFd &Pkg) APT_OVERRIDE;
+
    debStatusIndex(std::string const &File);
    virtual ~debStatusIndex();
 };
index 42eca8677fef61e00f20ec8fedefae82f9c6a5fc..d88e25e6fbd10d469528d0012e446f977e9d77a6 100644 (file)
@@ -362,7 +362,7 @@ unsigned short debListParser::VersionHash()
    return Result;
 }
                                                                        /*}}}*/
-// ListParser::ParseStatus - Parse the status field                    /*{{{*/
+// StatusListParser::ParseStatus - Parse the status field              /*{{{*/
 // ---------------------------------------------------------------------
 /* Status lines are of the form,
      Status: want flag status
@@ -373,6 +373,11 @@ unsigned short debListParser::VersionHash()
  */
 bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg,
                                pkgCache::VerIterator &Ver)
+{
+   return true;
+}
+bool debStatusListParser::ParseStatus(pkgCache::PkgIterator &Pkg,
+                               pkgCache::VerIterator &Ver)
 {
    const char *Start;
    const char *Stop;
index 747e022d8a4a395eddeae03c802f5a6966a2822a..0884479db7a512773da2db7f0f253c67031c666c 100644 (file)
@@ -119,4 +119,11 @@ class APT_HIDDEN debTranslationsParser : public debListParser
       : debListParser(File) {};
 };
 
+class APT_HIDDEN debStatusListParser : public debListParser
+{
+ public:
+   virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
+   debStatusListParser(FileFd *File)
+      : debListParser(File) {};
+};
 #endif
diff --git a/test/integration/test-security-no-remote-status b/test/integration/test-security-no-remote-status
new file mode 100755 (executable)
index 0000000..b7cd0b0
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Test that packages from remote sources cannot set the Status field.
+#
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64'
+
+TMPDIR=$(readlink -f .)
+
+insertpackage 'unstable' 'pretends-installed' 'all' '1' 'Status: install ok installed'
+insertinstalledpackage 'really-installed' 'all' '1'
+setupaptarchive
+
+testequal "pretends-installed:
+  Installed: (none)
+  Candidate: 1
+  Version table:
+     1 0
+        500 file:${TMPDIR}/aptarchive/ unstable/main amd64 Packages" aptcache policy pretends-installed
+
+testequal "really-installed:
+  Installed: 1
+  Candidate: 1
+  Version table:
+ *** 1 0
+        100 ${TMPDIR}/rootdir/var/lib/dpkg/status" aptcache policy really-installed