Forráskód Böngészése

dpkg: Add new --force-script-chrootless option

Currently, dpkg chroots to the instdir before invoking maintainer
scripts. The new force flag will inhibit the chroot call. The user
is supposed to know that the packages being operated on does support
this new mode of operation. Thus the force flag is marked as dangerous.

[guillem@debian.org:
 - Rename force option to --force-script-chrootless.
 - Reword force option description in man page.
 - Reactor changedir variable. ]

Ref: #804624
Signed-off-by: Guillem Jover <guillem@debian.org>
Helmut Grohne 10 éve
szülő
commit
85651f1788
5 módosított fájl, 20 hozzáadás és 5 törlés
  1. 2 0
      debian/changelog
  2. 9 1
      man/dpkg.1
  3. 3 0
      src/main.c
  4. 1 0
      src/main.h
  5. 5 4
      src/script.c

+ 2 - 0
debian/changelog

@@ -82,6 +82,8 @@ dpkg (1.18.5) UNRELEASED; urgency=medium
   * Add new -O option to dpkg-genchanges.
   * Make dpkg export variable DPKG_ROOT in maintainer scripts. Closes: #804624
     Thanks to Helmut Grohne <helmut@subdivi.de>.
+  * Add new --force-script-chrootless option to dpkg.
+    Thanks to Helmut Grohne <helmut@subdivi.de>.
   * Portability:
     - Move DPKG_ADMINDIR environment variable name out from update-alternatives
       code, to make life easier for non-dpkg-based systems.

+ 9 - 1
man/dpkg.1

@@ -601,6 +601,12 @@ any software not doing syncs before atomic renames.
 \fIWarning: Using this option might improve performance at the cost of
 losing data, use with care.\fP
 
+\fBscript-chrootless\fP:
+Run maintainer scrips without \fBchroot\fP(2)ing into \fBinstdir\fP even
+if the package does not support this mode of operation (since dpkg 1.18.5).
+
+\fIWarning: This can destroy your host system, use with extreme care.\fP
+
 \fBarchitecture\fP:
 Process even packages with wrong or no architecture.
 
@@ -865,7 +871,9 @@ operate on.
 During normal operation, this variable is empy.
 When installing packages into a different \fBinstdir\fP, \fBdpkg\fP
 normally invokes maintainer scripts using \fBchroot\fP(2) and leaves
-this variable empty.
+this variable empty, but if \fB\-\-force\-script\-chrootless\fP is
+specified then the \fBchroot\fP(2) call is skipped and \fBinstdir\fP
+is non-empty.
 .TP
 .B DPKG_SHELL_REASON
 Defined by \fBdpkg\fP on the shell spawned on the conffile prompt to

+ 3 - 0
src/main.c

@@ -196,6 +196,7 @@ int fc_conff_ask = 0;
 int fc_unsafe_io = 0;
 int fc_badverify = 0;
 int fc_badversion = 0;
+int fc_script_chrootless = 0;
 
 int errabort = 50;
 static const char *admindir = ADMINDIR;
@@ -248,6 +249,8 @@ static const struct forceinfo {
     '!', N_("Overwrite one package's directory with another's file") },
   { "unsafe-io",           &fc_unsafe_io,
     '!', N_("Do not perform safe I/O operations when unpacking") },
+  { "script-chrootless",   &fc_script_chrootless,
+    '!', N_("Do not chroot into maintainer script environment") },
   { "confnew",             &fc_conff_new,
     '!', N_("Always use the new config files, don't prompt") },
   { "confold",             &fc_conff_old,

+ 1 - 0
src/main.h

@@ -141,6 +141,7 @@ extern int fc_conff_ask;
 extern int fc_badverify;
 extern int fc_badversion;
 extern int fc_unsafe_io;
+extern int fc_script_chrootless;
 
 extern bool abort_processing;
 extern int errabort;

+ 5 - 4
src/script.c

@@ -98,9 +98,10 @@ static const char *
 maintscript_pre_exec(struct command *cmd)
 {
 	const char *admindir = dpkg_db_get_dir();
+	const char *changedir = fc_script_chrootless ? instdir : "/";
 	size_t instdirl = strlen(instdir);
 
-	if (*instdir) {
+	if (*instdir && !fc_script_chrootless) {
 		if (strncmp(admindir, instdir, instdirl) != 0)
 			ohshit(_("admindir must be inside instdir for dpkg to work properly"));
 		if (setenv("DPKG_ADMINDIR", admindir + instdirl, 1) < 0)
@@ -113,8 +114,8 @@ maintscript_pre_exec(struct command *cmd)
 	}
 	/* Switch to a known good directory to give the maintainer script
 	 * a saner environment, also needed after the chroot(). */
-	if (chdir("/"))
-		ohshite(_("failed to chdir to '%.255s'"), "/");
+	if (chdir(changedir))
+		ohshite(_("failed to chdir to '%.255s'"), changedir);
 	if (debug_has_flag(dbg_scripts)) {
 		struct varbuf args = VARBUF_INIT;
 		const char **argv = cmd->argv;
@@ -128,7 +129,7 @@ maintscript_pre_exec(struct command *cmd)
 		      args.buf);
 		varbuf_destroy(&args);
 	}
-	if (!instdirl)
+	if (!instdirl || fc_script_chrootless)
 		return cmd->filename;
 
 	assert(strlen(cmd->filename) >= instdirl);