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

Reply via email to