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