Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock

Hi!

I'd like to upload dpkg 1.17.22 with the following changes. I've
excluded and filtered translation changes. I'm including a patch series
instead of a debdiff, because it should be clearer and easier to spot
specific changes you might not want to approve?

This passes all unit tests, and the functional tests (which I've fixed
to comply) from <https://anonscm.debian.org/cgit/dpkg/dpkg-tests.git>.
In addition, I've got some status files that trigger some of the bugs,
that I've not yet synthetized, which work fine with the new dpkg. I've
also been running this on my main system with daily upgrades for over
a week now.

Thanks,
Guillem
From 2d3adc759c37bf73c12730c79b73dc26ca171c7d Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Thu, 6 Nov 2014 18:13:27 +0100
Subject: [PATCH 01/12] man: Add when dpkg-deb --ctrl-tarfile got introduced

Missed in commit 03c0873bd720a4f93db0cc4764fa98d3dbcadede.
---
 debian/changelog    |  3 +++
 man/dpkg-deb.1      |  2 +-
 man/po/de.po        | 12 +++++++-----
 man/po/dpkg-man.pot |  8 ++++----
 man/po/es.po        |  8 ++++----
 man/po/fr.po        | 12 ++++++------
 man/po/hu.po        |  8 ++++----
 man/po/it.po        |  8 ++++----
 man/po/ja.po        |  8 ++++----
 man/po/pl.po        |  8 ++++----
 man/po/pt_BR.po     |  8 ++++----
 man/po/ru.po        |  8 ++++----
 man/po/sv.po        | 14 +++++++-------
 13 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index a02a208..7e34751 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,8 @@
 dpkg (1.17.22) UNRELEASED; urgency=low
 
+  [ Guillem Jover ]
+  * Add version introducing --ctrl-tarfile in dpkg-deb(1) man page.
+
   [ Updated programs translations ]
   * German (Sven Joachim).
   * French (Sébastien Poher).
diff --git a/man/dpkg-deb.1 b/man/dpkg-deb.1
index 09c066c..c5038ec 100644
--- a/man/dpkg-deb.1
+++ b/man/dpkg-deb.1
@@ -174,7 +174,7 @@ The target directory (but not its parents) will be created if necessary.
 Extracts the control data from a binary package and sends it to standard
 output in
 .B tar
-format. Together with
+format (since dpkg 1.17.14). Together with
 .BR tar (1)
 this can be used to extract a particular control file from a package archive.
 The input archive will always be processed sequentially.
-- 
2.1.3

From e04dd68c0a36e465a656a9e78830dcf28e455242 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Mon, 17 Nov 2014 00:55:20 +0100
Subject: [PATCH 02/12] man: Bump minimal version for dir_to_symlink and
 symlink_to_dir commands

The minimal version for dir_to_symlink with all current features is
1.17.13, and for symlink_to_dir is 1.17.14. But to make it simpler,
let's just say the latter. This also avoids unnecessary translator
work.

Missed in commits 7fe9dcdd57c083180a7994957d1e5217d28e970a and
a92a3ac5056363e9c21c48187f6ff965481742f4.

Closes: #769843
---
 debian/changelog              |  2 ++
 man/dpkg-maintscript-helper.1 |  4 ++--
 man/po/de.po                  | 10 +++++-----
 man/po/fr.po                  | 10 +++++-----
 man/po/sv.po                  | 10 +++++-----
 5 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 7e34751..ec5b9cd 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,8 @@ dpkg (1.17.22) UNRELEASED; urgency=low
 
   [ Guillem Jover ]
   * Add version introducing --ctrl-tarfile in dpkg-deb(1) man page.
+  * Bump minimal version for dir_to_symlink and symlink_to_dir commands
+    to 1.17.14 in dpkg-maintscript-helper(1) man page. Closes: #769843
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/man/dpkg-maintscript-helper.1 b/man/dpkg-maintscript-helper.1
index 908083d..85185ac 100644
--- a/man/dpkg-maintscript-helper.1
+++ b/man/dpkg-maintscript-helper.1
@@ -230,9 +230,9 @@ using it unconditionally requires a pre-dependency to ensure that the
 required version of \fBdpkg\fP has been unpacked before. The required version
 depends on the command used, for \fBrm_conffile\fP and \fBmv_conffile\fP
 it is 1.15.7.2, for \fBsymlink_to_dir\fP and \fBdir_to_symlink\fP
-it is 1.17.5:
+it is 1.17.14:
 .P
-    \fBPre\-Depends:\fP dpkg (>= 1.17.5)
+    \fBPre\-Depends:\fP dpkg (>= 1.17.14)
 .P
 But in many cases the operation done by the program is not critical for
 the package, and instead of using a pre-dependency we can call the
-- 
2.1.3

From a213746672a3e12a8ef6b86ccf04594bf30e8fba Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Sun, 9 Nov 2014 00:51:42 +0100
Subject: [PATCH 03/12] debian: Reintroduce u-a, dpkg-divert and
 dpkg-statoverride compat symlinks

There are still packages using those paths, but the relevant lintian
check did not list any, so these got removed prematurely.
---
 Makefile.am       | 1 +
 TODO              | 2 ++
 debian/changelog  | 4 ++++
 debian/dpkg.links | 3 +++
 4 files changed, 10 insertions(+)
 create mode 100644 debian/dpkg.links

diff --git a/Makefile.am b/Makefile.am
index a829c98..aa13270 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -55,6 +55,7 @@ EXTRA_DIST = \
 	debian/dpkg.preinst \
 	debian/dpkg.prerm \
 	debian/dpkg.logrotate \
+	debian/dpkg.links \
 	debian/dpkg.lintian-overrides \
 	debian/dselect.cfg \
 	debian/dselect.docs \
diff --git a/TODO b/TODO
index 11d7037..7275cdf 100644
--- a/TODO
+++ b/TODO
@@ -91,6 +91,8 @@ TODO
 
  * We should set our own obstack_alloc_failed_handler.
 
+ * Remove compatibility symlinks
+   /usr/sbin/{update-alternatives,dpkg-divert,dpkg-statoverride}.
 
 ------------------------------------------------------------------------------
 
diff --git a/debian/changelog b/debian/changelog
index ec5b9cd..473d243 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,10 @@ dpkg (1.17.22) UNRELEASED; urgency=low
   * Add version introducing --ctrl-tarfile in dpkg-deb(1) man page.
   * Bump minimal version for dir_to_symlink and symlink_to_dir commands
     to 1.17.14 in dpkg-maintscript-helper(1) man page. Closes: #769843
+  * Reintroduce update-alternatives, dpkg-divert and dpkg-statoverride
+    compatibility symlinks under /usr/sbin/. There are still packages
+    using those paths, but the relevant lintian check did not list any,
+    so this got removed prematurely.
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/debian/dpkg.links b/debian/dpkg.links
new file mode 100644
index 0000000..429ab15
--- /dev/null
+++ b/debian/dpkg.links
@@ -0,0 +1,3 @@
+usr/bin/dpkg-divert usr/sbin/dpkg-divert
+usr/bin/dpkg-statoverride usr/sbin/dpkg-statoverride
+usr/bin/update-alternatives usr/sbin/update-alternatives
-- 
2.1.3

From b89caa796ac54ca86db33c6b06e72a122975bf0e Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Wed, 19 Nov 2014 21:49:08 +0100
Subject: [PATCH 04/12] debian: Add Breaks on man-db, fontconfig and
 readahead-fedora

The old versions of these packages produced trigger cycles as they
were using awaiting trigger directives.

Closes: #768599
---
 debian/changelog | 2 ++
 debian/control   | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 473d243..e5f6955 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -8,6 +8,8 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     compatibility symlinks under /usr/sbin/. There are still packages
     using those paths, but the relevant lintian check did not list any,
     so this got removed prematurely.
+  * Add Breaks on old man-db, fontconfig and readahead-fedora packages using
+    awaiting triggers, as they produce trigger cycles. Closes: #768599
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/debian/control b/debian/control
index e0c0158..4653a47 100644
--- a/debian/control
+++ b/debian/control
@@ -36,6 +36,10 @@ Essential: yes
 Pre-Depends: ${shlibs:Depends}, tar (>= 1.23)
 Depends: ${misc:Depends}
 Breaks: dpkg-dev (<< 1.15.8), libdpkg-perl (<< 1.15.8),
+# These cause trigger cycles due to using awaiting trigger directives.
+ man-db (<< 2.6.3-6), fontconfig (<< 2.11.0-6.2),
+ readahead-fedora (<< 2:1.5.6-5.2),
+# These do not support triggers.
  apt (<< 0.7.7), aptitude (<< 0.4.7-1)
 Conflicts:
 # The following Conflicts against removed packages using install-info
-- 
2.1.3

From 446f11df6302716c2a1f993761ee54ecb44d42bb Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Fri, 7 Nov 2014 20:49:26 +0100
Subject: [PATCH 05/12] libdpkg: Escape package and architecture on control
 file parsing warning

The package and architecture names are injected into a variable that is
used as a format string. Because these are user controlled, we need to
format-escape them so that they become inert.

Regression introduced in commmit 3be2cf607868adb9a2c0e5af06f20168a072eeb6.

Fixes: CVE-2014-8625
Closes: #768485
Reporteb-by: Joshua Rogers <megaman...@gmail.com>
---
 debian/changelog     |  5 +++++
 lib/dpkg/parsehelp.c | 11 +++++++----
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index e5f6955..a1cad38 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -10,6 +10,11 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     so this got removed prematurely.
   * Add Breaks on old man-db, fontconfig and readahead-fedora packages using
     awaiting triggers, as they produce trigger cycles. Closes: #768599
+  * Escape package and architecture names on control file parsing warning,
+    as those get injected into a variable that is used as a format string,
+    and they come from the package fields, which are under user control.
+    Regression introduced in dpkg 1.16.0. Fixes CVE-2014-8625. Closes: #768485
+    Reported by Joshua Rogers <megaman...@gmail.com>.
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/lib/dpkg/parsehelp.c b/lib/dpkg/parsehelp.c
index e091f67..3537de1 100644
--- a/lib/dpkg/parsehelp.c
+++ b/lib/dpkg/parsehelp.c
@@ -44,11 +44,14 @@ parse_error_msg(struct parsedb_state *ps, const char *fmt)
 
   str_escape_fmt(filename, ps->filename, sizeof(filename));
 
-  if (ps->pkg && ps->pkg->set->name)
+  if (ps->pkg && ps->pkg->set->name) {
+    char pkgname[256];
+
+    str_escape_fmt(pkgname, pkgbin_name(ps->pkg, ps->pkgbin, pnaw_nonambig),
+                   sizeof(pkgname));
     sprintf(msg, _("parsing file '%.255s' near line %d package '%.255s':\n"
-                   " %.255s"), filename, ps->lno,
-                   pkgbin_name(ps->pkg, ps->pkgbin, pnaw_nonambig), fmt);
-  else
+                   " %.255s"), filename, ps->lno, pkgname, fmt);
+  } else
     sprintf(msg, _("parsing file '%.255s' near line %d:\n"
                    " %.255s"), filename, ps->lno, fmt);
 
-- 
2.1.3

From 611305ef0e85092cc24887e040c19e9e808dd633 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Tue, 11 Nov 2014 17:37:04 +0100
Subject: [PATCH 06/12] libdpkg: Do not match partial field names in control
 files

There is currently no instance of any misspelled field names known to
dpkg in Debian. Only known field names are possibly affected.

Regression introduced in commit 864e230e90de1cef94c81f10582e6d99717d593b.

Closes: #769119
---
 debian/changelog | 2 ++
 lib/dpkg/parse.c | 6 ++++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index a1cad38..817ef06 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -15,6 +15,8 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     and they come from the package fields, which are under user control.
     Regression introduced in dpkg 1.16.0. Fixes CVE-2014-8625. Closes: #768485
     Reported by Joshua Rogers <megaman...@gmail.com>.
+  * Do not match partial field names in control files. Closes: #769119
+    Regression introduced in dpkg 1.10.
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/lib/dpkg/parse.c b/lib/dpkg/parse.c
index 5824769..604e7ad 100644
--- a/lib/dpkg/parse.c
+++ b/lib/dpkg/parse.c
@@ -131,7 +131,8 @@ pkg_parse_field(struct parsedb_state *ps, struct field_state *fs,
   }
 
   for (fip = fieldinfos, ip = fs->fieldencountered; fip->name; fip++, ip++)
-    if (strncasecmp(fip->name, fs->fieldstart, fs->fieldlen) == 0)
+    if (strncasecmp(fip->name, fs->fieldstart, fs->fieldlen) == 0 &&
+        fip->name[fs->fieldlen] == '\0')
       break;
   if (fip->name) {
     if ((*ip)++)
@@ -152,7 +153,8 @@ pkg_parse_field(struct parsedb_state *ps, struct field_state *fs,
                   fs->fieldlen, fs->fieldstart);
     larpp = &pkg_obj->pkgbin->arbs;
     while ((arp = *larpp) != NULL) {
-      if (strncasecmp(arp->name, fs->fieldstart, fs->fieldlen) == 0)
+      if (strncasecmp(arp->name, fs->fieldstart, fs->fieldlen) == 0 &&
+          arp->name[fs->fieldlen] == '\0')
         parse_error(ps,
                    _("duplicate value for user-defined field `%.*s'"),
                    fs->fieldlen, fs->fieldstart);
-- 
2.1.3

From bd3f720ca063c581ca5c446ba8bb9b3318d6dd3d Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Wed, 12 Nov 2014 00:57:55 +0100
Subject: [PATCH 07/12] libdpkg: Fix fd_allocate_size() function to build on
 Mac OS X

Add missing semicolons to fcntl() call, and rename fs_preallocate_setup()
call sites to fd_preallocate_setup() on Mac OS X codepath.

Regression introduced in commit 87b0b20b86407baf1deb4e91b3fd839e01228ac8.

Reported-by: Dominyk Tiller <dominyktil...@gmail.com>
---
 debian/changelog | 2 ++
 lib/dpkg/fdio.c  | 8 ++++----
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 817ef06..322c954 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -17,6 +17,8 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     Reported by Joshua Rogers <megaman...@gmail.com>.
   * Do not match partial field names in control files. Closes: #769119
     Regression introduced in dpkg 1.10.
+  * Fix build on Mac OS X. Regression introduced in dpkg 1.17.11.
+    Reported by Dominyk Tiller <dominyktil...@gmail.com>.
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/lib/dpkg/fdio.c b/lib/dpkg/fdio.c
index 9ac2128..38781c8 100644
--- a/lib/dpkg/fdio.c
+++ b/lib/dpkg/fdio.c
@@ -109,13 +109,13 @@ fd_allocate_size(int fd, off_t offset, off_t len)
 	/* On Mac OS X. */
 	fstore_t fs;
 
-	fs_preallocate_setup(&fs, F_ALLOCATECONTIG, offset, len);
-	rc = fcntl(fd, F_PREALLOCATE, &fs)
+	fd_preallocate_setup(&fs, F_ALLOCATECONTIG, offset, len);
+	rc = fcntl(fd, F_PREALLOCATE, &fs);
 	if (rc < 0 && errno == ENOSPC) {
 		/* If we cannot get a contiguous allocation, then try
 		 * non-contiguous. */
-		fs_preallocate_setup(&fs, F_ALLOCATEALL, offset, len);
-		rc = fcntl(fd, F_PREALLOCATE, &fs)
+		fd_preallocate_setup(&fs, F_ALLOCATEALL, offset, len);
+		rc = fcntl(fd, F_PREALLOCATE, &fs);
 	}
 #elif defined(HAVE_F_ALLOCSP64)
 	/* On Solaris. */
-- 
2.1.3

From b1c19bc87eb661f074e63a2aa5c8ac9e55e3fac4 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Wed, 12 Nov 2014 10:17:08 +0100
Subject: [PATCH 08/12] libdpkg, dpkg: Normalize tar entry uid and gid only in
 dpkg unpack

The tar extractor should be independent from the current system, so that
testing it can be made reproducible.

Move the preference over the system user and group names to the actual
dpkg unpack code.

Regression introduced in commit f71e02c8e913884bfbf9d97b58ded4591b823cdb.

Closes: #769211
---
 debian/changelog |  2 ++
 lib/dpkg/tarfn.c | 37 +++++++++++++++++++++++++------------
 lib/dpkg/tarfn.h |  3 +++
 src/archives.c   |  2 ++
 4 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 322c954..2fa248f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -19,6 +19,8 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     Regression introduced in dpkg 1.10.
   * Fix build on Mac OS X. Regression introduced in dpkg 1.17.11.
     Reported by Dominyk Tiller <dominyktil...@gmail.com>.
+  * Normalize tar entry uid and gid from the current system only in dpkg
+    unpack. Regression introduced in dpkg 1.17.14. Closes: #769211
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/lib/dpkg/tarfn.c b/lib/dpkg/tarfn.c
index bde1927..71a58f1 100644
--- a/lib/dpkg/tarfn.c
+++ b/lib/dpkg/tarfn.c
@@ -157,8 +157,6 @@ tar_header_checksum(struct tar_header *h)
 static int
 tar_header_decode(struct tar_header *h, struct tar_entry *d)
 {
-	struct passwd *passwd = NULL;
-	struct group *group = NULL;
 	long checksum;
 
 	if (memcmp(h->magic, TAR_MAGIC_GNU, 6) == 0)
@@ -185,26 +183,18 @@ tar_header_decode(struct tar_header *h, struct tar_entry *d)
 			 OtoM(h->devminor, sizeof(h->devminor)));
 
 	if (*h->user) {
-		passwd = getpwnam(h->user);
 		d->stat.uname = m_strndup(h->user, sizeof(h->user));
 	} else {
 		d->stat.uname = NULL;
 	}
-	if (passwd)
-		d->stat.uid = passwd->pw_uid;
-	else
-		d->stat.uid = (uid_t)OtoM(h->uid, sizeof(h->uid));
+	d->stat.uid = (uid_t)OtoM(h->uid, sizeof(h->uid));
 
 	if (*h->group) {
-		group = getgrnam(h->group);
 		d->stat.gname = m_strndup(h->group, sizeof(h->group));
 	} else {
 		d->stat.gname = NULL;
 	}
-	if (group)
-		d->stat.gid = group->gr_gid;
-	else
-		d->stat.gid = (gid_t)OtoM(h->gid, sizeof(h->gid));
+	d->stat.gid = (gid_t)OtoM(h->gid, sizeof(h->gid));
 
 	checksum = OtoM(h->checksum, sizeof(h->checksum));
 
@@ -287,6 +277,29 @@ struct symlinkList {
 	struct tar_entry h;
 };
 
+/**
+ * Update the tar entry from system information.
+ *
+ * Normalize UID and GID relative to the current system.
+ */
+void
+tar_entry_update_from_system(struct tar_entry *te)
+{
+	struct passwd *passwd;
+	struct group *group;
+
+	if (te->stat.uname) {
+		passwd = getpwnam(te->stat.uname);
+		if (passwd)
+			te->stat.uid = passwd->pw_uid;
+	}
+	if (te->stat.gname) {
+		group = getgrnam(te->stat.gname);
+		if (group)
+			te->stat.gid = group->gr_gid;
+	}
+}
+
 int
 tar_extractor(void *ctx, const struct tar_operations *ops)
 {
diff --git a/lib/dpkg/tarfn.h b/lib/dpkg/tarfn.h
index 89f27eb..ce69424 100644
--- a/lib/dpkg/tarfn.h
+++ b/lib/dpkg/tarfn.h
@@ -87,6 +87,9 @@ struct tar_operations {
 	tar_make_func *mknod;
 };
 
+void
+tar_entry_update_from_system(struct tar_entry *te);
+
 int tar_extractor(void *ctx, const struct tar_operations *ops);
 
 /** @} */
diff --git a/src/archives.c b/src/archives.c
index 8f6b4cf..9b3aefc 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -789,6 +789,8 @@ tarobject(void *ctx, struct tar_entry *ti)
 
   ensureobstackinit();
 
+  tar_entry_update_from_system(ti);
+
   /* Append to list of files.
    * The trailing ‘/’ put on the end of names in tarfiles has already
    * been stripped by tar_extractor(). */
-- 
2.1.3

From c4e109999d90e99199754e3e419ef90477b2a046 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Tue, 11 Nov 2014 19:49:48 +0100
Subject: [PATCH 09/12] dpkg: Restore multiple processing checks for packages
 and archives

The notices about duplicate entries not being processed got suppressed
when the requeueing insertion protection got enabled. Add a new variable
to track when packages or archives have been processed more than once.

Regression introduced in commit ce27f5dc0c3dc6ed7656d09784ea461407765d7d.
---
 debian/changelog |  2 ++
 src/filesdb.c    |  1 +
 src/main.h       |  2 ++
 src/packages.c   | 19 +++++++++++++------
 src/unpack.c     |  2 +-
 5 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 2fa248f..21ba80b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -21,6 +21,8 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     Reported by Dominyk Tiller <dominyktil...@gmail.com>.
   * Normalize tar entry uid and gid from the current system only in dpkg
     unpack. Regression introduced in dpkg 1.17.14. Closes: #769211
+  * Restore multiple processing instances check for packages and archives
+    specified on the command-line. Regression introduced in dpkg 1.17.20.
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/src/filesdb.c b/src/filesdb.c
index 59d93e1..759fe9a 100644
--- a/src/filesdb.c
+++ b/src/filesdb.c
@@ -109,6 +109,7 @@ ensure_package_clientdata(struct pkginfo *pkg)
   pkg->clientdata->fileslistvalid = false;
   pkg->clientdata->files = NULL;
   pkg->clientdata->replacingfilesandsaid = 0;
+  pkg->clientdata->cmdline_seen = 0;
   pkg->clientdata->listfile_phys_offs = 0;
   pkg->clientdata->trigprocdeferred = NULL;
 }
diff --git a/src/main.h b/src/main.h
index eafea87..e199635 100644
--- a/src/main.h
+++ b/src/main.h
@@ -64,6 +64,7 @@ struct perpackagestate {
   bool fileslistvalid;
   struct fileinlist *files;
   int replacingfilesandsaid;
+  int cmdline_seen;
 
   off_t listfile_phys_offs;
 
@@ -193,6 +194,7 @@ int clearselections(const char *const *argv);
 
 void md5hash(struct pkginfo *pkg, char *hashbuf, const char *fn);
 void enqueue_package(struct pkginfo *pkg);
+void enqueue_package_mark_seen(struct pkginfo *pkg);
 void process_queue(void);
 int packages(const char *const *argv);
 void removal_bulk(struct pkginfo *pkg);
diff --git a/src/packages.c b/src/packages.c
index 62d7495..abafc5a 100644
--- a/src/packages.c
+++ b/src/packages.c
@@ -63,6 +63,13 @@ enqueue_package(struct pkginfo *pkg)
   pkg_queue_push(&queue, pkg);
 }
 
+void
+enqueue_package_mark_seen(struct pkginfo *pkg)
+{
+  enqueue_package(pkg);
+  pkg->clientdata->cmdline_seen++;
+}
+
 static void
 enqueue_pending(void)
 {
@@ -119,7 +126,7 @@ enqueue_specified(const char *const *argv)
       badusage(_("you must specify packages by their own names, "
                  "not by quoting the names of the files they come in"));
     }
-    enqueue_package(pkg);
+    enqueue_package_mark_seen(pkg);
   }
 }
 
@@ -185,8 +192,10 @@ void process_queue(void) {
   }
   for (rundown = queue.head; rundown; rundown = rundown->next) {
     ensure_package_clientdata(rundown->pkg);
-    if (rundown->pkg->clientdata->istobe == istobe) {
-      /* Erase the queue entry - this is a second copy! */
+
+    /* We have processed this package more than once. There are no duplicates
+     * as we make sure of that when enqueuing them. */
+    if (rundown->pkg->clientdata->cmdline_seen > 1) {
       switch (cipaction->arg_int) {
       case act_triggers:
       case act_configure: case act_remove: case act_purge:
@@ -201,10 +210,8 @@ void process_queue(void) {
       default:
         internerr("unknown action '%d'", cipaction->arg_int);
       }
-      rundown->pkg = NULL;
-   } else {
-      rundown->pkg->clientdata->istobe= istobe;
     }
+    rundown->pkg->clientdata->istobe = istobe;
   }
 
   while (!pkg_queue_is_empty(&queue)) {
diff --git a/src/unpack.c b/src/unpack.c
index a44f478..7562c3c 100644
--- a/src/unpack.c
+++ b/src/unpack.c
@@ -1480,5 +1480,5 @@ void process_archive(const char *filename) {
   }
 
   if (cipaction->arg_int == act_install)
-    enqueue_package(pkg);
+    enqueue_package_mark_seen(pkg);
 }
-- 
2.1.3

From 9a9ba74915876449b1fe20d4b76ab759f7d09d86 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Thu, 13 Nov 2014 12:10:42 +0100
Subject: [PATCH 10/12] dpkg: Fail on trigger processing when it is required to
 progress

Trigger processing is sometimes required and sometimes opportunistic.
When trying to make progress on the packages queue, we need to consider
it an error if the dependencies cannot be satisfied in this run. But if
we are running the deferred trigger processing, then we should not fail,
as that's just opportunistic.

Closes: #768852
---
 debian/changelog |  3 +++
 src/main.h       |  9 ++++++++-
 src/packages.c   |  2 +-
 src/trigproc.c   | 20 +++++++++++++++++---
 src/unpack.c     |  2 +-
 5 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 21ba80b..ce5d3d8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -23,6 +23,9 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     unpack. Regression introduced in dpkg 1.17.14. Closes: #769211
   * Restore multiple processing instances check for packages and archives
     specified on the command-line. Regression introduced in dpkg 1.17.20.
+  * Fail on trigger processing when it is required to progress. Trigger
+    processing is sometimes required and sometimes opportunistic, and we
+    should only fail on the former but ignore the latter. Closes: #768852
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/src/main.h b/src/main.h
index e199635..0d79514 100644
--- a/src/main.h
+++ b/src/main.h
@@ -272,11 +272,18 @@ void log_action(const char *action, struct pkginfo *pkg, struct pkgbin *pkgbin);
 
 /* from trigproc.c */
 
+enum trigproc_type {
+	/** Opportunistic trigger processing. */
+	TRIGPROC_TRY,
+	/** Required trigger processing. */
+	TRIGPROC_REQUIRED,
+};
+
 void trigproc_install_hooks(void);
 void trigproc_run_deferred(void);
 void trigproc_reset_cycle(void);
 
-void trigproc(struct pkginfo *pkg);
+void trigproc(struct pkginfo *pkg, enum trigproc_type type);
 
 void trig_activate_packageprocessing(struct pkginfo *pkg);
 
diff --git a/src/packages.c b/src/packages.c
index abafc5a..3aad4ab 100644
--- a/src/packages.c
+++ b/src/packages.c
@@ -278,7 +278,7 @@ void process_queue(void) {
     case act_configure:
       /* Do whatever is most needed. */
       if (pkg->trigpend_head)
-        trigproc(pkg);
+        trigproc(pkg, TRIGPROC_REQUIRED);
       else
         deferred_configure(pkg);
       break;
diff --git a/src/trigproc.c b/src/trigproc.c
index 965e5c5..4d61d70 100644
--- a/src/trigproc.c
+++ b/src/trigproc.c
@@ -124,7 +124,7 @@ trigproc_run_deferred(void)
 		                        pkg_name(pkg, pnaw_nonambig));
 
 		pkg->clientdata->trigprocdeferred = NULL;
-		trigproc(pkg);
+		trigproc(pkg, TRIGPROC_TRY);
 
 		pop_error_context(ehflag_normaltidy);
 	}
@@ -312,7 +312,7 @@ check_trigger_cycle(struct pkginfo *processing_now)
  * that case does nothing but fix up any stale awaiters.
  */
 void
-trigproc(struct pkginfo *pkg)
+trigproc(struct pkginfo *pkg, enum trigproc_type type)
 {
 	static struct varbuf namesarg;
 
@@ -347,8 +347,22 @@ trigproc(struct pkginfo *pkg)
 			enqueue_package(pkg);
 			return;
 		} else if (ok == DEP_CHECK_HALT) {
+			/* When doing opportunistic trigger processig, nothing
+			 * requires us to be able to make progress; skip the
+			 * package and silently ignore the error due to
+			 * unsatisfiable dependencies. */
+			if (type == TRIGPROC_TRY) {
+				varbuf_destroy(&depwhynot);
+				return;
+			}
+
+			sincenothing = 0;
+			varbuf_end_str(&depwhynot);
+			notice(_("dependency problems prevent processing "
+			         "triggers for %s:\n%s"),
+			       pkg_name(pkg, pnaw_nonambig), depwhynot.buf);
 			varbuf_destroy(&depwhynot);
-			return;
+			ohshit(_("dependency problems - leaving triggers unprocessed"));
 		} else if (depwhynot.used) {
 			varbuf_end_str(&depwhynot);
 			notice(_("%s: dependency problems, but processing "
diff --git a/src/unpack.c b/src/unpack.c
index 7562c3c..954b6b5 100644
--- a/src/unpack.c
+++ b/src/unpack.c
@@ -669,7 +669,7 @@ void process_archive(const char *filename) {
       if (!depisok(dsearch, &depprobwhy, NULL, &fixbytrigaw, true)) {
         if (fixbytrigaw) {
           while (fixbytrigaw->trigaw.head)
-            trigproc(fixbytrigaw->trigaw.head->pend);
+            trigproc(fixbytrigaw->trigaw.head->pend, TRIGPROC_REQUIRED);
         } else {
           varbuf_end_str(&depprobwhy);
           notice(_("regarding %s containing %s, pre-dependency problem:\n%s"),
-- 
2.1.3

From 54526e8773218199ef588c17509ec6fc5c044da7 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Thu, 13 Nov 2014 23:49:15 +0100
Subject: [PATCH 11/12] dpkg: Do not ignore trigger cycles for direct
 dependencies

These are just normal trigger cycles, and as such should not be special
cased. And a strict reading of the triggers spec does not allow them
either. It might make sense to allow self-cycles, but avoiding cycles
from direct dependencies does not make much sense.
---
 debian/changelog |  2 ++
 src/packages.c   | 18 ------------------
 2 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index ce5d3d8..e58d88d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -26,6 +26,8 @@ dpkg (1.17.22) UNRELEASED; urgency=low
   * Fail on trigger processing when it is required to progress. Trigger
     processing is sometimes required and sometimes opportunistic, and we
     should only fail on the former but ignore the latter. Closes: #768852
+  * Do not ignore trigger cycles for direct dependencies, these are just
+    normal trigger cycles, and as such should not be special cased.
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/src/packages.c b/src/packages.c
index 3aad4ab..6ccedfe 100644
--- a/src/packages.c
+++ b/src/packages.c
@@ -439,24 +439,6 @@ deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby,
         debug(dbg_depcondetail, "      triggers-awaited, no fixbytrig");
         goto unsuitable;
       }
-      /* If we have a dependency cycle where a package A awaits trigger
-       * processing and package P has them pending, and both depend on each
-       * other, the dependency cycle breaking code is not smart enough to
-       * break it at the correct place, as the relationship is directional.
-       * So we handle it specially here.
-       *
-       * Otherwise we just defer it, but do not record that it can be fixed
-       * by trigger processing, because we would get into an inifite loop. */
-      if (requiredby == possdependee->trigaw.head->pend) {
-        if (dependtry > 1) {
-          debug(dbg_depcondetail, "      triggers-awaited, fixed by us, "
-                                  "break cycle so ok and found");
-          return FOUND_OK;
-        } else {
-          debug(dbg_depcondetail, "      triggers-awaited, fixed by us, defer");
-          return FOUND_DEFER;
-        }
-      }
       /* We don't check the status of trigaw.head->pend here, just in case
        * we get into the pathological situation where Triggers-Awaited but
        * the named package doesn't actually have any pending triggers. In
-- 
2.1.3

From 75a857d79d3d3a5cb8367bbd49d5e89bb94af0a1 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Fri, 14 Nov 2014 18:35:32 +0100
Subject: [PATCH 12/12] libdpkg: Register all pending triggers for deferred
 processing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Trigger processing on the deferred stage is just opportunistic, but
we enqueue all currently pending triggers that might have been
activated on a previous unpack run, only when being called as
«dpkg --configure pkgname…».

This is a mostly conformant workaround for frontends like apt that do
not correctly call «dpkg --configure -a» or «dpkg --triggers-only -a»
after their normal runs, and leave packages in triggers-pending and
triggers-awaited states.

Closes: #766758
---
 debian/changelog |  5 +++++
 src/main.h       |  1 +
 src/packages.c   |  3 +++
 src/trigproc.c   | 38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 47 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index e58d88d..ba10d7e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -28,6 +28,11 @@ dpkg (1.17.22) UNRELEASED; urgency=low
     should only fail on the former but ignore the latter. Closes: #768852
   * Do not ignore trigger cycles for direct dependencies, these are just
     normal trigger cycles, and as such should not be special cased.
+  * Register all pending triggers for deferred processing when being called
+    as «dpkg --configure pkgname…». This is a mostly conformant workaround
+    for frontends like apt that do not correctly call «dpkg --configure -a»
+    or «dpkg --triggers-only -a» after their normal runs, and leave packages
+    in triggers-pending and triggers-awaited states. Closes: #766758
 
   [ Updated programs translations ]
   * German (Sven Joachim).
diff --git a/src/main.h b/src/main.h
index 0d79514..1f84cca 100644
--- a/src/main.h
+++ b/src/main.h
@@ -280,6 +280,7 @@ enum trigproc_type {
 };
 
 void trigproc_install_hooks(void);
+void trigproc_populate_deferred(void);
 void trigproc_run_deferred(void);
 void trigproc_reset_cycle(void);
 
diff --git a/src/packages.c b/src/packages.c
index 6ccedfe..52cca36 100644
--- a/src/packages.c
+++ b/src/packages.c
@@ -128,6 +128,9 @@ enqueue_specified(const char *const *argv)
     }
     enqueue_package_mark_seen(pkg);
   }
+
+  if (cipaction->arg_int == act_configure)
+    trigproc_populate_deferred();
 }
 
 int
diff --git a/src/trigproc.c b/src/trigproc.c
index 4d61d70..ea91c74 100644
--- a/src/trigproc.c
+++ b/src/trigproc.c
@@ -103,6 +103,44 @@ trigproc_enqueue_deferred(struct pkginfo *pend)
 	      pkg_name(pend, pnaw_always));
 }
 
+/**
+ * Populate the deferred trigger queue.
+ *
+ * When dpkg is called with a specific set of packages to act on, we might
+ * have packages pending trigger processing. But because there are frontends
+ * that do not perform a final «dpkg --configure --pending» call (i.e. apt),
+ * the system is left in a state with packages not fully installed.
+ *
+ * We have to populate the deferred trigger queue from the entire package
+ * database, so that we might try to do opportunistic trigger processing
+ * when going through the deferred trigger queue, because a fixed apt will
+ * not request the necessary processing anyway.
+ *
+ * XXX: This can be removed once apt is fixed in the next stable release.
+ */
+void
+trigproc_populate_deferred(void)
+{
+	struct pkgiterator *iter;
+	struct pkginfo *pkg;
+
+	iter = pkg_db_iter_new();
+	while ((pkg = pkg_db_iter_next_pkg(iter))) {
+		if (!pkg->trigpend_head)
+			continue;
+
+		if (pkg->status != PKG_STAT_TRIGGERSAWAITED &&
+		    pkg->status != PKG_STAT_TRIGGERSPENDING)
+			continue;
+
+		if (pkg->want != PKG_WANT_INSTALL)
+			continue;
+
+		trigproc_enqueue_deferred(pkg);
+	}
+	pkg_db_iter_free(iter);
+}
+
 void
 trigproc_run_deferred(void)
 {
-- 
2.1.3

Reply via email to