Explorar el Código

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
Guillem Jover hace 11 años
padre
commit
b1c19bc87e
Se han modificado 4 ficheros con 32 adiciones y 12 borrados
  1. 2 0
      debian/changelog
  2. 25 12
      lib/dpkg/tarfn.c
  3. 3 0
      lib/dpkg/tarfn.h
  4. 2 0
      src/archives.c

+ 2 - 0
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 <dominyktiller@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).

+ 25 - 12
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)
 {

+ 3 - 0
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);
 
 /** @} */

+ 2 - 0
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(). */