diff options
author | Paul Nasrat <pnasrat@redhat.com> | 2007-04-16 13:26:12 +0100 |
---|---|---|
committer | Paul Nasrat <pnasrat@redhat.com> | 2007-04-16 13:26:12 +0100 |
commit | 0e863398d4c4f8b750b41e0eeeb643d3b9ebbf06 (patch) | |
tree | c6cecdd12c30073b3208fc20a4b7adb6919728b2 | |
parent | a6368d35530243b8d6bb0ca302a16c903f967921 (diff) | |
download | librpm-tizen-0e863398d4c4f8b750b41e0eeeb643d3b9ebbf06.tar.gz librpm-tizen-0e863398d4c4f8b750b41e0eeeb643d3b9ebbf06.tar.bz2 librpm-tizen-0e863398d4c4f8b750b41e0eeeb643d3b9ebbf06.zip |
When deleting files, drop any s-bit first, so that a malicious
user does not have access to old programs if he hard links them
to some other directory. [#50376] rh#125517
Patch from OpenSuSE
-rw-r--r-- | lib/cpio.h | 3 | ||||
-rw-r--r-- | lib/fsm.c | 5 | ||||
-rw-r--r-- | lib/psm.c | 2 | ||||
-rw-r--r-- | lib/transaction.c | 24 |
4 files changed, 32 insertions, 2 deletions
diff --git a/lib/cpio.h b/lib/cpio.h index c716097da..46c6fdd62 100644 --- a/lib/cpio.h +++ b/lib/cpio.h @@ -64,7 +64,8 @@ typedef enum cpioMapFlags_e { CPIO_MAP_ABSOLUTE = (1 << 5), CPIO_MAP_ADDDOT = (1 << 6), CPIO_ALL_HARDLINKS = (1 << 7), /*!< fail if hardlinks are missing. */ - CPIO_MAP_TYPE = (1 << 8) /*!< only for building. */ + CPIO_MAP_TYPE = (1 << 8), /*!< only for building. */ + CPIO_SBIT_CHECK = (1 << 9) } cpioMapFlags; #define CPIO_NEWC_MAGIC "070701" @@ -2127,6 +2127,11 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break; /*@notreached@*/ break; case FSM_UNLINK: + if (fsm->mapFlags & CPIO_SBIT_CHECK) { + struct stat stb; + if (Lstat(fsm->path, &stb) == 0 && S_ISREG(stb.st_mode) && (stb.st_mode & 06000) != 0) + chmod(fsm->path, stb.st_mode & 0777); + } rc = Unlink(fsm->path); if (_fsm_debug && (stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s (%s) %s\n", cur, @@ -1472,7 +1472,7 @@ assert(psm->mi == NULL); fi->striplen = (xx ? strlen(p) + 1 : 1); } fi->mapflags = - CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID; + CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID | (fi->mapflags & CPIO_SBIT_CHECK); if (headerIsEntry(fi->h, RPMTAG_ORIGBASENAMES)) rpmfiBuildFNames(fi->h, RPMTAG_ORIGBASENAMES, &fi->apath, NULL); diff --git a/lib/transaction.c b/lib/transaction.c index 2822a66c8..cac8e7f7c 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -187,6 +187,13 @@ static int handleInstInstalledFiles(const rpmts ts, if (XFA_SKIPPING(fi->actions[fileNum])) continue; + if (!(fi->mapflags & CPIO_SBIT_CHECK)) { + int_16 omode = rpmfiFMode(otherFi); + if (S_ISREG(omode) && (omode & 06000) != 0) { + fi->mapflags |= CPIO_SBIT_CHECK; + } + } + if (rpmfiCompare(otherFi, fi)) { int rConflicts; @@ -1846,6 +1853,20 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); case TR_REMOVED: /*@switchbreak@*/ break; } + /* check for s-bit files to be removed */ + if (rpmteType(p) == TR_REMOVED) { + fi = rpmfiInit(fi, 0); + while ((i = rpmfiNext(fi)) >= 0) { + int_16 mode; + if (XFA_SKIPPING(fi->actions[i])) + continue; + (void) rpmfiSetFX(fi, i); + mode = rpmfiFMode(fi); + if (S_ISREG(mode) && (mode & 06000) != 0) { + fi->mapflags |= CPIO_SBIT_CHECK; + } + } + } (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc); } pi = rpmtsiFree(pi); @@ -2091,6 +2112,7 @@ assert(psm != NULL); { char * fstates = fi->fstates; fileAction * actions = fi->actions; + int mapflags = fi->mapflags; rpmte savep; fi->fstates = NULL; @@ -2109,6 +2131,8 @@ assert(psm != NULL); fi->fstates = fstates; fi->actions = _free(fi->actions); fi->actions = actions; + if (mapflags & CPIO_SBIT_CHECK) + fi->mapflags |= CPIO_SBIT_CHECK; p->fi = fi; } } |