Просмотр исходного кода

dpkg: fix possible segfault in findbreakcycle().

The circumstances are not entirely clear because clear_istobes() is
called earlier in the code and should already ensure that clientdata
is allocated for all packages in the database but the stack trace
reported leaves no room for any other interpretation. We must protect
the access to tpkg->clientdata in findbreakcycle() with
ensure_package_clientdata(tpkg).

Probably that some other parts of the code might create new packages in the
in-memory database depending on some specific conditions. It might be that
those conditions only hold for a multiarch-enabled dpkg for example if
the code looks up a package entry for an alternative architecture and
would thus create the package on the fly.

This is pure speculation because I did not push the investigations that
far. It might be something entirely different but it doesn't matter much
because the proposed fix is the same and just ensures that we respect
our API by protecting the access to clientdata.

See https://bugs.launchpad.net/ubuntu/+source/dpkg/+bug/733414 for
details.
Raphaël Hertzog лет назад: 15
Родитель
Сommit
e135afdb35
2 измененных файлов с 3 добавлено и 0 удалено
  1. 1 0
      debian/changelog
  2. 2 0
      src/depcon.c

+ 1 - 0
debian/changelog

@@ -155,6 +155,7 @@ dpkg (1.16.1) UNRELEASED; urgency=low
   * Refer to Sources and Packages files as part of a repository instead of
     as being of exclusive use or owned by APT, which has never been the case.
   * Unify somewhat dpkg-maintscript-helper --help output with other commands.
+  * Fix possible segfault of dpkg in findbreakcycle(). LP: #733414
 
   [ Bill Allombert]
   * Add support for Build-Features: build-arch. Closes: #229357

+ 2 - 0
src/depcon.c

@@ -32,6 +32,7 @@
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
 
+#include "filesdb.h"
 #include "infodb.h"
 #include "main.h"
 
@@ -157,6 +158,7 @@ findbreakcycle(struct pkginfo *pkg)
   /* Clear the visited flag of all packages before we traverse them. */
   iter = pkg_db_iter_new();
   while ((tpkg = pkg_db_iter_next(iter))) {
+    ensure_package_clientdata(tpkg);
     tpkg->clientdata->color = white;
   }
   pkg_db_iter_free(iter);