diff options
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 @@ | |||
1 | We need to sanity check that the nlink size and our linksLeft counter | ||
2 | do match. If an rpm is badly constructed with identical inode values | ||
3 | for multiple hardlinked files, such an rpm will otherwise access memory | ||
4 | out of array bounds and cause memory corruption and crashes. | ||
5 | |||
6 | The fix is to add in the sanity check and exit if bad circumstances | ||
7 | are found. We need to fix the caller to check the return code too. | ||
8 | |||
9 | RP 2014/6/10 | ||
10 | |||
11 | Upstream-Status: Pending | ||
12 | |||
13 | Index: 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 @@ | |||
1 | If we run builds on a filesystem with 64 bit inodes like XFS, we need to | ||
2 | map the inode numbers to something 32 bit since the cpio header only allows | ||
3 | for 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 | |||
9 | from cpio.c will print larger that 8 character values and then truncate the | ||
10 | LSBs. This generates cpio files where hardlinked files may have the same | ||
11 | inode number. The resulting rpms are then corrupted. | ||
12 | |||
13 | There is a separate patch for the crash the identical inode numbers causes | ||
14 | when extracting the rpm. | ||
15 | |||
16 | Patch taken from http://git.pld-linux.org/?p=packages/rpm.git;a=commitdiff;h=10526c23aac60b7b636e4c93862887dbef8e8f15 | ||
17 | |||
18 | RP 2014/6/10 | ||
19 | |||
20 | Upstream-Status: Pending | ||
21 | |||
22 | diff -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 |