RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 27-Feb-2016 22:46:10 Branch: rpm-5_4 Handle: 2016022721461000 Modified files: (Branch: rpm-5_4) rpm/lib fsm.c rpm/rpmio iosm.c Log: 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 Summary: Revision Changes Path 2.193.4.9 +11 -1 rpm/lib/fsm.c 1.43.2.7 +12 -2 rpm/rpmio/iosm.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/lib/fsm.c ============================================================================ $ cvs diff -u -r2.193.4.8 -r2.193.4.9 fsm.c --- rpm/lib/fsm.c 10 Sep 2014 20:10:05 -0000 2.193.4.8 +++ rpm/lib/fsm.c 27 Feb 2016 21:46:10 -0000 2.193.4.9 @@ -496,6 +496,11 @@ } if (fsm->goal == IOSM_PKGBUILD) --fsm->li->linksLeft; + if (fsm->li->linksLeft > (int)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; @@ -1881,8 +1886,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; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/iosm.c ============================================================================ $ cvs diff -u -r1.43.2.6 -r1.43.2.7 iosm.c --- rpm/rpmio/iosm.c 19 Jul 2014 18:58:57 -0000 1.43.2.6 +++ rpm/rpmio/iosm.c 27 Feb 2016 21:46:10 -0000 1.43.2.7 @@ -518,6 +518,11 @@ } if (iosm->goal == IOSM_PKGBUILD) --iosm->li->linksLeft; + if (iosm->li->linksLeft > (int) st->st_nlink) { + rpmlog(RPMLOG_ERR, _("Corrupted hardlinks found (count %d does not match %d), exiting.\n"), iosm->li->linksLeft, st->st_nlink); + return -1; + } + iosm->li->filex[iosm->li->linksLeft] = iosm->ix; /*@-observertrans -dependenttrans@*/ iosm->li->nsuffix[iosm->li->linksLeft] = iosm->nsuffix; @@ -1918,8 +1923,13 @@ iosm->postpone = iosmFileActionSkipped(iosm->action); if (iosm->goal == IOSM_PKGINSTALL || iosm->goal == IOSM_PKGBUILD) { /*@-evalorder@*/ /* FIX: saveHardLink can modify iosm */ - if (S_ISREG(st->st_mode) && st->st_nlink > 1) - iosm->postpone = saveHardLink(iosm); + if (S_ISREG(st->st_mode) && st->st_nlink > 1) { + iosm->postpone = saveHardLink(iosm); + if (iosm->postpone < 0) { + rc = RPMRC_FAIL; + break; + } + } /*@=evalorder@*/ } { rpmfi fi = (rpmfi) iosmGetFi(iosm); @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org