[oe-commits] Richard Purdie : rpm: Fix cpio 32 bit overflow issues on 64 bit inode filesystems

git at git.openembedded.org git at git.openembedded.org
Tue Jun 10 16:44:22 UTC 2014


Module: openembedded-core.git
Branch: master-next
Commit: c39749a18cb839a228209dd6f30ddda31da4bcdf
URL:    http://git.openembedded.org/?p=openembedded-core.git&a=commit;h=c39749a18cb839a228209dd6f30ddda31da4bcdf

Author: Richard Purdie <richard.purdie at linuxfoundation.org>
Date:   Tue Jun 10 17:32:16 2014 +0100

rpm: Fix cpio 32 bit overflow issues on 64 bit inode filesystems

When building on XFS filesystems, the resulting rpms can be corrupted
with the same inode number being used for multiple hardlinked files.
There are two fixes, one to stop rpm crashing when accessing a broken
binary rpm, the other to stop generating them in the first places. Full
descriptions in the patch headers.

Signed-off-by: Richard Purdie <richard.purdie at linuxfoundation.org>

---

 .../rpm/rpm/rpm-hardlink-segfault-fix.patch        | 43 ++++++++++++++++++++++
 .../rpm/rpm/rpm-payload-use-hashed-inode.patch     | 39 ++++++++++++++++++++
 meta/recipes-devtools/rpm/rpm_5.4.9.bb             |  2 +
 3 files changed, 84 insertions(+)

diff --git a/meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch b/meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch
new file mode 100644
index 0000000..cb67e69
--- /dev/null
+++ b/meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch
@@ -0,0 +1,43 @@
+We need to sanity check that the nlink size and our linksLeft counter
+do match. If an rpm is badly constructed with identical inode values
+for multiple hardlinked files, such an rpm will otherwise access memory
+out of array bounds and cause memory corruption and crashes.
+
+The fix is to add in the sanity check and exit if bad circumstances
+are found. We need to fix the caller to check the return code too.
+
+RP 10/6/2014
+
+Upstream-Status: Pending
+
+Index: rpm-5.4.9/lib/fsm.c
+===================================================================
+--- rpm-5.4.9.orig/lib/fsm.c	2014-06-10 10:54:08.601049402 +0000
++++ rpm-5.4.9/lib/fsm.c	2014-06-10 10:55:45.633046077 +0000
+@@ -495,6 +495,11 @@
+     }
+ 
+     if (fsm->goal == IOSM_PKGBUILD) --fsm->li->linksLeft;
++    if (fsm->li->linksLeft > st->st_nlink) {
++	rpmlog(RPMLOG_ERR, _("Corrupted hardlinks found (count %d does not match %d), exiting.\n"), fsm->li->linksLeft, st->st_nlink);
++	return -1;
++    }
++
+     fsm->li->filex[fsm->li->linksLeft] = fsm->ix;
+     /*@-observertrans -dependenttrans@*/
+     fsm->li->nsuffix[fsm->li->linksLeft] = fsm->nsuffix;
+@@ -1876,8 +1881,13 @@
+ 	fsm->postpone = iosmFileActionSkipped(fsm->action);
+ 	if (fsm->goal == IOSM_PKGINSTALL || fsm->goal == IOSM_PKGBUILD) {
+ 	    /*@-evalorder@*/ /* FIX: saveHardLink can modify fsm */
+-	    if (S_ISREG(st->st_mode) && st->st_nlink > 1)
++	    if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
+ 		fsm->postpone = saveHardLink(fsm);
++		if (fsm->postpone < 0) {
++		    rc = RPMRC_FAIL;
++		    break;
++		}
++	    }
+ 	    /*@=evalorder@*/
+ 	}
+ if (fsmGetFi(fsm)->mapflags & IOSM_PAYLOAD_LIST) fsm->postpone = 1;
diff --git a/meta/recipes-devtools/rpm/rpm/rpm-payload-use-hashed-inode.patch b/meta/recipes-devtools/rpm/rpm/rpm-payload-use-hashed-inode.patch
new file mode 100644
index 0000000..abfacc9
--- /dev/null
+++ b/meta/recipes-devtools/rpm/rpm/rpm-payload-use-hashed-inode.patch
@@ -0,0 +1,39 @@
+If we run builds on a filesystem with 64 bit inodes like XFS, we need to
+map the inode numbers to something 32 bit since the cpio header only allows
+for 32 bit inode values. If we don't do this:
+
+#define SET_NUM_FIELD(phys, val, space) \
+        sprintf(space, "%8.8lx", (unsigned long) (val)); \
+        memcpy(phys, space, 8)
+
+from cpio.c will print larger that 8 character values and then truncate the 
+LSBs. This generates cpio files where hardlinked files may have the same
+inode number. The resulting rpms are then corrupted.
+
+There is a separate patch for the crash the identical inode numbers causes
+when extracting the rpm.
+
+Patch taken from http://git.pld-linux.org/?p=packages/rpm.git;a=commitdiff;h=10526c23aac60b7b636e4c93862887dbef8e8f15
+
+RP 10/6/2014
+
+Upstream-Status: Pending
+
+--- rpm-5.4.10/lib/fsm.c~
++++ rpm-5.4.10/lib/fsm.c
+@@ -898,6 +898,7 @@ int fsmMapAttrs(IOSM_t fsm)
+ 
+     if (fi && i >= 0 && i < (int) fi->fc) {
+ 	mode_t perms = (S_ISDIR(st->st_mode) ? fi->dperms : fi->fperms);
++	ino_t finalInode = (fi->finodes ? (ino_t)fi->finodes[i] : 0);
+ 	mode_t finalMode = (fi->fmodes ? (mode_t)fi->fmodes[i] : perms);
+ 	dev_t finalRdev = (dev_t)(fi->frdevs ? fi->frdevs[i] : 0);
+ 	rpmuint32_t finalMtime = (fi->fmtimes ? fi->fmtimes[i] : 0);
+@@ -937,6 +938,7 @@ int fsmMapAttrs(IOSM_t fsm)
+ 	    if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
+ 	    && st->st_nlink == 0)
+ 		st->st_nlink = 1;
++	    st->st_ino = finalInode;
+ 	    st->st_rdev = finalRdev;
+ 	    st->st_mtime = finalMtime;
+ 	}
diff --git a/meta/recipes-devtools/rpm/rpm_5.4.9.bb b/meta/recipes-devtools/rpm/rpm_5.4.9.bb
index 43f46ed..6934749 100644
--- a/meta/recipes-devtools/rpm/rpm_5.4.9.bb
+++ b/meta/recipes-devtools/rpm/rpm_5.4.9.bb
@@ -91,6 +91,8 @@ SRC_URI = "http://www.rpm5.org/files/rpm/rpm-5.4/rpm-5.4.9-0.20120508.src.rpm;ex
 	   file://rpm-lsb-compatibility.patch \
 	   file://rpm-tag-generate-endian-conversion-fix.patch \
 	   file://rpm-verify-files.patch \
+	   file://rpm-payload-use-hashed-inode.patch \
+	   file://rpm-hardlink-segfault-fix.patch \
 	  "
 
 # Uncomment the following line to enable platform score debugging



More information about the Openembedded-commits mailing list