Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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.14/lib/fsm.c |
| 14 | =================================================================== |
| 15 | --- rpm-5.4.14.orig/lib/fsm.c |
| 16 | +++ rpm-5.4.14/lib/fsm.c |
| 17 | @@ -495,6 +495,11 @@ static int saveHardLink(/*@special@*/ /* |
| 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 | @@ -1878,8 +1883,13 @@ if (!(fsmGetFi(fsm)->mapflags & IOSM_PAY |
| 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; |