diff options
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.patch | 43 |
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; |