[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

multiarch: dpkg-query segfaults



Hi Guillem and Raphaël,

Being the adventurous sort, I tried building and installing dpkg from
guillem/pu/multiarch/master.  "dpkg" seems to work ok, but dpkg-query
is broken (it always segfaults).

Ok, back to dpkg/sid (thanks for the maintainer scripts that make
switching between very easy).  Luckily the segfault is reproducible
without installing a new dpkg version:

	$ build-tree/src/dpkg-query -l dpkg
	Segmentation fault

Also reproducible with raphael/pu/multiarch/full.  Bisects to 8c57a40d
(libdpkg: update package sorting logic to take into account the
architecture), which didn't take into account that some callers of
pkg_sorter_by_name leave pkg->installed and pkg->available blank (the
juicy stuff for them seems to be in pkg->set).

The diff below [1] works around it.

We get another segfault in the same spirit (same reproduction recipe)
in 26516da (dpkg-query: Update commands to accept package specifiers
as arguments).  It is due to this code:

|      for (i = 0; i < array.n_pkgs; i++) {
|        pkg = array.pkgs[i];
|        for (ip = 0; ip < argc; ip++) {
| -        if (!fnmatch(argv[ip], pkg->set->name, 0)) {
| +        if (pkg_spec_match_pkg(&ps[ip], pkg, &pkg->installed)) {

"dpkg-query -l dpkg:amd64" seems to work fine.

I guess that is because when the commandline parameter does not
include an architecture specifier, pkgs[i]->installed.arch is examined
to check if it's a native package, and since arch is NULL, segfault.

So the diff below [1] works around that, too.

Another oddity:

	$ dpkg-query --search -- /lib/x86_64-linux-gnu/libc.so.6
	strcpy: /lib/x86_64-linux-gnu/libc.so.6

Bisects to 3c971ae (dpkg-query: Update --list and --show to output
package specifiers)

Hints?
Jonathan

[1]

 lib/dpkg/pkg-spec.c |    4 ++++
 lib/dpkg/pkg.c      |    7 +++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/dpkg/pkg-spec.c b/lib/dpkg/pkg-spec.c
index 2859bad8..ee119c78 100644
--- a/lib/dpkg/pkg-spec.c
+++ b/lib/dpkg/pkg-spec.c
@@ -141,6 +141,10 @@ pkg_spec_parse(struct pkg_spec *ps, const char *str)
 static bool
 pkg_spec_match_arch(struct pkg_spec *ps, const struct dpkg_arch *arch)
 {
+	/* These should just never match. */
+	if (!arch)
+		return false;
+
 	if (ps->arch_is_pattern)
 		return (fnmatch(ps->arch->name, arch->name, 0) == 0);
 	else if (ps->arch->type != arch_none) /* !arch_is_pattern */
diff --git a/lib/dpkg/pkg.c b/lib/dpkg/pkg.c
index 2dc00d9b..1495c1d0 100644
--- a/lib/dpkg/pkg.c
+++ b/lib/dpkg/pkg.c
@@ -136,8 +136,8 @@ pkg_sorter_by_name(const void *a, const void *b)
 {
 	const struct pkginfo *pa = *(const struct pkginfo **)a;
 	const struct pkginfo *pb = *(const struct pkginfo **)b;
-	const char *arch_a = pa->installed.arch->name;
-	const char *arch_b = pb->installed.arch->name;
+	const char *arch_a;
+	const char *arch_b;
 	int res;
 
 	res = strcmp(pa->set->name, pb->set->name);
@@ -155,5 +155,8 @@ pkg_sorter_by_name(const void *a, const void *b)
             pb->installed.arch->type == arch_native)
 		arch_b = "";
 
+	arch_b = pb->installed.arch->name;
+	arch_a = pa->installed.arch->name;
+
 	return strcmp(arch_a, arch_b);
 }
-- 
1.7.8.rc3


Reply to: