summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/rpm
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2014-06-10 17:32:16 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-06-12 17:47:59 +0100
commitdd50dfe27ea5be5bfc9f1b4f1ce4f1bf421498b6 (patch)
tree7eae0c14d984f0ef61d3f50b8d27e8a19d98bfef /meta/recipes-devtools/rpm
parentb5a928af721026795be7b7f68b2dd577408afbe5 (diff)
downloadpoky-dd50dfe27ea5be5bfc9f1b4f1ce4f1bf421498b6.tar.gz
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. (From OE-Core rev: d20d3476157b7c949b0077cad0ab1e8716d6162a) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/rpm')
-rw-r--r--meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch43
-rw-r--r--meta/recipes-devtools/rpm/rpm/rpm-payload-use-hashed-inode.patch144
-rw-r--r--meta/recipes-devtools/rpm/rpm_5.4.9.bb2
3 files changed, 189 insertions, 0 deletions
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 0000000000..8c2a04a3d5
--- /dev/null
+++ b/meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch
@@ -0,0 +1,43 @@
1We need to sanity check that the nlink size and our linksLeft counter
2do match. If an rpm is badly constructed with identical inode values
3for multiple hardlinked files, such an rpm will otherwise access memory
4out of array bounds and cause memory corruption and crashes.
5
6The fix is to add in the sanity check and exit if bad circumstances
7are found. We need to fix the caller to check the return code too.
8
9RP 2014/6/10
10
11Upstream-Status: Pending
12
13Index: rpm-5.4.9/lib/fsm.c
14===================================================================
15--- rpm-5.4.9.orig/lib/fsm.c 2014-06-10 10:54:08.601049402 +0000
16+++ rpm-5.4.9/lib/fsm.c 2014-06-10 10:55:45.633046077 +0000
17@@ -495,6 +495,11 @@
18 }
19
20 if (fsm->goal == IOSM_PKGBUILD) --fsm->li->linksLeft;
21+ if (fsm->li->linksLeft > st->st_nlink) {
22+ rpmlog(RPMLOG_ERR, _("Corrupted hardlinks found (count %d does not match %d), exiting.\n"), fsm->li->linksLeft, st->st_nlink);
23+ return -1;
24+ }
25+
26 fsm->li->filex[fsm->li->linksLeft] = fsm->ix;
27 /*@-observertrans -dependenttrans@*/
28 fsm->li->nsuffix[fsm->li->linksLeft] = fsm->nsuffix;
29@@ -1876,8 +1881,13 @@
30 fsm->postpone = iosmFileActionSkipped(fsm->action);
31 if (fsm->goal == IOSM_PKGINSTALL || fsm->goal == IOSM_PKGBUILD) {
32 /*@-evalorder@*/ /* FIX: saveHardLink can modify fsm */
33- if (S_ISREG(st->st_mode) && st->st_nlink > 1)
34+ if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
35 fsm->postpone = saveHardLink(fsm);
36+ if (fsm->postpone < 0) {
37+ rc = RPMRC_FAIL;
38+ break;
39+ }
40+ }
41 /*@=evalorder@*/
42 }
43 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 0000000000..fc6b218300
--- /dev/null
+++ b/meta/recipes-devtools/rpm/rpm/rpm-payload-use-hashed-inode.patch
@@ -0,0 +1,144 @@
1If we run builds on a filesystem with 64 bit inodes like XFS, we need to
2map the inode numbers to something 32 bit since the cpio header only allows
3for 32 bit inode values. If we don't do this:
4
5#define SET_NUM_FIELD(phys, val, space) \
6 sprintf(space, "%8.8lx", (unsigned long) (val)); \
7 memcpy(phys, space, 8)
8
9from cpio.c will print larger that 8 character values and then truncate the
10LSBs. This generates cpio files where hardlinked files may have the same
11inode number. The resulting rpms are then corrupted.
12
13There is a separate patch for the crash the identical inode numbers causes
14when extracting the rpm.
15
16Patch taken from http://git.pld-linux.org/?p=packages/rpm.git;a=commitdiff;h=10526c23aac60b7b636e4c93862887dbef8e8f15
17
18RP 2014/6/10
19
20Upstream-Status: Pending
21
22diff -ur rpm-5.4.10/build/files.c rpm-5.4.10-collision/build/files.c
23--- rpm-5.4.10/build/files.c 2013-03-17 13:17:38.233358389 +0100
24+++ rpm-5.4.10-collision/build/files.c 2013-03-17 13:07:37.468483625 +0100
25@@ -1323,6 +1323,26 @@
26 return dalgo;
27 }
28
29+static int isHardLink(FileListRec flp, FileListRec tlp)
30+{
31+ return ((S_ISREG(flp->fl_mode) && S_ISREG(tlp->fl_mode)) &&
32+ ((flp->fl_nlink > 1) && (flp->fl_nlink == tlp->fl_nlink)) &&
33+ (flp->fl_ino == tlp->fl_ino) &&
34+ (flp->fl_dev == tlp->fl_dev));
35+}
36+
37+static int seenHardLink(FileList fl, FileListRec flp, ino_t *fileid)
38+{
39+ FileListRec ilp;
40+ for (ilp = fl->fileList; ilp < flp; ilp++) {
41+ if (isHardLink(flp, ilp)) {
42+ *fileid = ilp - fl->fileList;
43+ return 1;
44+ }
45+ }
46+ return 0;
47+}
48+
49 /**
50 * Add file entries to header.
51 * @todo Should directories have %doc/%config attributes? (#14531)
52@@ -1370,6 +1390,7 @@
53
54 for (i = 0, flp = fl->fileList; i < fl->fileListRecsUsed; i++, flp++) {
55 const char *s;
56+ ino_t fileid = flp - fl->fileList;
57
58 /* Merge duplicate entries. */
59 while (i < (fl->fileListRecsUsed - 1) &&
60@@ -1437,6 +1458,13 @@
61 /* Leave room for both dirname and basename NUL's */
62 dpathlen += (strlen(flp->diskURL) + 2);
63
64+ /* Excludes and dupes have been filtered out by now. */
65+ if (S_ISREG(flp->fl_mode)) {
66+ if (flp->fl_nlink == 1 || !seenHardLink(fl, flp, &fileid)) {
67+ fl->totalFileSize += flp->fl_size;
68+ }
69+ }
70+
71 /*
72 * Make the header, the OLDFILENAMES will get converted to a
73 * compressed file list write before we write the actual package to
74@@ -1519,7 +1547,11 @@
75
76 /* XXX Hash instead of 64b->32b truncate to prevent aliasing. */
77 { ino_t _ino = flp->fl_ino;
78- ui32 = hashFunctionString(0, &_ino, sizeof(_ino));
79+ /* don't use hash here, as hash collisions which happen on large packages
80+ cause bus errors in rpmbuild
81+ ui32 = hashFunctionString(0, &_ino, sizeof(_ino));
82+ */
83+ ui32 = fileid + 1;
84 }
85 he->tag = RPMTAG_FILEINODES;
86 he->t = RPM_UINT32_TYPE;
87@@ -1752,39 +1780,6 @@
88 IOSM_MAP_TYPE | IOSM_MAP_MODE | IOSM_MAP_UID | IOSM_MAP_GID;
89 if (isSrc)
90 fi->fmapflags[i] |= IOSM_FOLLOW_SYMLINKS;
91-
92- if (S_ISREG(flp->fl_mode)) {
93- int bingo = 1;
94- /* Hard links need be tallied only once. */
95- if (flp->fl_nlink > 1) {
96- FileListRec jlp = flp + 1;
97- int j = i + 1;
98- for (; (unsigned)j < fi->fc; j++, jlp++) {
99- /* follow outer loop logic */
100- while (((jlp - fl->fileList) < (fl->fileListRecsUsed - 1)) &&
101- !strcmp(jlp->fileURL, jlp[1].fileURL))
102- jlp++;
103- if (jlp->flags & RPMFILE_EXCLUDE) {
104- j--;
105- /*@innercontinue@*/ continue;
106- }
107- if (jlp->flags & RPMFILE_GHOST)
108- /*@innercontinue@*/ continue;
109- if (!S_ISREG(jlp->fl_mode))
110- /*@innercontinue@*/ continue;
111- if (flp->fl_nlink != jlp->fl_nlink)
112- /*@innercontinue@*/ continue;
113- if (flp->fl_ino != jlp->fl_ino)
114- /*@innercontinue@*/ continue;
115- if (flp->fl_dev != jlp->fl_dev)
116- /*@innercontinue@*/ continue;
117- bingo = 0; /* don't tally hardlink yet. */
118- /*@innerbreak@*/ break;
119- }
120- }
121- if (bingo)
122- fl->totalFileSize += flp->fl_size;
123- }
124 }
125
126 ui32 = fl->totalFileSize;
127--- rpm-5.4.10/lib/fsm.c~
128+++ rpm-5.4.10/lib/fsm.c
129@@ -898,6 +898,7 @@ int fsmMapAttrs(IOSM_t fsm)
130
131 if (fi && i >= 0 && i < (int) fi->fc) {
132 mode_t perms = (S_ISDIR(st->st_mode) ? fi->dperms : fi->fperms);
133+ ino_t finalInode = (fi->finodes ? (ino_t)fi->finodes[i] : 0);
134 mode_t finalMode = (fi->fmodes ? (mode_t)fi->fmodes[i] : perms);
135 dev_t finalRdev = (dev_t)(fi->frdevs ? fi->frdevs[i] : 0);
136 rpmuint32_t finalMtime = (fi->fmtimes ? fi->fmtimes[i] : 0);
137@@ -937,6 +938,7 @@ int fsmMapAttrs(IOSM_t fsm)
138 if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
139 && st->st_nlink == 0)
140 st->st_nlink = 1;
141+ st->st_ino = finalInode;
142 st->st_rdev = finalRdev;
143 st->st_mtime = finalMtime;
144 }
diff --git a/meta/recipes-devtools/rpm/rpm_5.4.9.bb b/meta/recipes-devtools/rpm/rpm_5.4.9.bb
index 43f46ed024..690d8b423a 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
91 file://rpm-lsb-compatibility.patch \ 91 file://rpm-lsb-compatibility.patch \
92 file://rpm-tag-generate-endian-conversion-fix.patch \ 92 file://rpm-tag-generate-endian-conversion-fix.patch \
93 file://rpm-verify-files.patch \ 93 file://rpm-verify-files.patch \
94 file://rpm-hardlink-segfault-fix.patch \
95 file://rpm-payload-use-hashed-inode.patch \
94 " 96 "
95 97
96# Uncomment the following line to enable platform score debugging 98# Uncomment the following line to enable platform score debugging