Parcourir la source

dpkg: ensure that trig_transitional_activate() doesn't introduce bad data

trig_transitional_activate() is emptying Triggers-Pending without
ensuring that the status is set back to something which is not
triggers-pending. In theory it's ok because the trig_parse_ci()
call is supposed to reactivate all the triggers. But if there's no
triggers file any more then we're effectively introducing a skew
which is going to be fatal the next time we try to write down
the status file.

The disparition of the triggers file can happen with file system problems,
bad user manipulation or even an old dpkg bug that kept triggers alive
when in fact the trigger was dropped from the package. Or the triggers
file has effectively been removed in the package but the user has restored
an old status file with a triggers-pending status that the current package
should no longer be able to generate.

In other words, properly resetting the status in
trig_transitional_activate() makes dpkg more robust.
Raphaël Hertzog il y a 15 ans
Parent
commit
a36cadba41
2 fichiers modifiés avec 9 ajouts et 0 suppressions
  1. 2 0
      debian/changelog
  2. 7 0
      src/trigproc.c

+ 2 - 0
debian/changelog

@@ -38,6 +38,8 @@ dpkg (1.16.1) UNRELEASED; urgency=low
     debian/source/patch-header. Closes: #629582
   * Changed dpkg-source --after-build to automatically unapply patches that it
     has applied during --before-build.
+  * Fix one possible cause for the assertion failure "pigp->trigpend_head".
+    LP: #798793
 
   [ Guillem Jover ]
   * Install deb-src-control(5) man pages in dpkg-dev. Closes: #620520

+ 7 - 0
src/trigproc.c

@@ -387,6 +387,13 @@ trig_transitional_activate(enum modstatdb_rw cstatus)
 		              cstatus >= msdbrw_write ?
 		              transitional_interest_callback :
 		              transitional_interest_callback_ro, NULL, pkg);
+		/* Ensure we're not creating incoherent data that can't
+		 * be written down. This should never happen in theory but
+		 * can happen if you restore an old status file that is
+		 * not in sync with the infodb files. */
+		pkg->status = pkg->trigaw.head ? stat_triggersawaited :
+		              pkg->trigpend_head ? stat_triggerspending :
+		              stat_installed;
 	}
 	pkg_db_iter_free(it);