summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Nasrat <pnasrat@redhat.com>2007-04-16 13:26:12 +0100
committerPaul Nasrat <pnasrat@redhat.com>2007-04-16 13:26:12 +0100
commit0e863398d4c4f8b750b41e0eeeb643d3b9ebbf06 (patch)
treec6cecdd12c30073b3208fc20a4b7adb6919728b2
parenta6368d35530243b8d6bb0ca302a16c903f967921 (diff)
downloadlibrpm-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.h3
-rw-r--r--lib/fsm.c5
-rw-r--r--lib/psm.c2
-rw-r--r--lib/transaction.c24
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"
diff --git a/lib/fsm.c b/lib/fsm.c
index 43334df13..40b71d7b1 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -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,
diff --git a/lib/psm.c b/lib/psm.c
index ffe28d904..852e40175 100644
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -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;
}
}