aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch')
-rw-r--r--meta/recipes-devtools/rpm/rpm/rpm-hardlink-segfault-fix.patch43
1 files changed, 43 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 @@
+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 2014/6/10
+
+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;