Sanitize selinux labeling in fsm

- Move all the label foobar into a simple helper function which
  finds, sets and frees the context if selinux is enabled, use
  for both regular operation and orphan directory labeling.
  Simplifies things a good deal...
- While the selabel handle can change during a transaction, it
  wont change while the fsm is running so its sufficient to grab
  it on entry instead of repeatedly calling rpmtsSELabelHandle() after
  figuring out where in the world our ts might be.
This commit is contained in:
Panu Matilainen 2012-01-13 11:08:47 +02:00
parent cc1b352952
commit d4b8acc5d3
2 changed files with 28 additions and 58 deletions

View File

@ -597,6 +597,7 @@ static int fsmSetup(FSM_t fsm, fileStage goal,
fsm->iter = mapInitIterator(ts, te, fi);
fsm->digestalgo = rpmfiDigestAlgo(fi);
fsm->psm = psm;
fsm->sehandle = rpmtsSELabelHandle(ts);
fsm->mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
if (goal == FSM_PKGBUILD) {
@ -659,22 +660,32 @@ static int fsmTeardown(FSM_t fsm)
return rc;
}
static int fsmMapFContext(FSM_t fsm)
/* Find and set file security context */
static int fsmSetSELabel(struct selabel_handle *sehandle,
const char *path, mode_t mode)
{
rpmts ts = fsmGetTs(fsm);
/*
* Find file security context (if not disabled).
*/
fsm->fcontext = NULL;
if (ts != NULL && !(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS) && rpmtsSELabelHandle(ts)) {
int rc = 0;
#if WITH_SELINUX
if (sehandle) {
security_context_t scon = NULL;
if (selabel_lookup_raw(rpmtsSELabelHandle(ts), &scon, fsm->path, fsm->sb.st_mode) == 0 && scon != NULL) {
fsm->fcontext = scon;
if (selabel_lookup_raw(sehandle, &scon, path, mode) == 0) {
rc = lsetfilecon(path, scon);
if (_fsm_debug && (FSM_LSETFCON & FSM_SYSCALL)) {
rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n",
fileStageString(FSM_LSETFCON), path, scon,
(rc < 0 ? strerror(errno) : ""));
}
if (rc < 0 && errno == EOPNOTSUPP)
rc = 0;
}
return 0;
freecon(scon);
}
#endif
return rc ? CPIOERR_LSETFCON_FAILED : 0;
}
#if WITH_CAP
@ -1140,21 +1151,6 @@ static int fsmRmdir(FSM_t fsm)
return rc;
}
static int fsmLsetfcon(FSM_t fsm)
{
int rc = 0;
if (fsm->fcontext == NULL || *fsm->fcontext == '\0'
|| rstreq(fsm->fcontext, "<<none>>"))
return rc;
rc = lsetfilecon(fsm->path, (security_context_t)fsm->fcontext);
if (_fsm_debug && (FSM_LSETFCON & FSM_SYSCALL))
rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n", fileStageString(FSM_LSETFCON),
fsm->path, fsm->fcontext,
(rc < 0 ? strerror(errno) : ""));
if (rc < 0) rc = (errno == EOPNOTSUPP ? 0 : CPIOERR_LSETFCON_FAILED);
return rc;
}
static int fsmMkdir(FSM_t fsm)
{
int rc = mkdir(fsm->path, (fsm->sb.st_mode & 07777));
@ -1186,8 +1182,6 @@ static int fsmMkdirs(FSM_t fsm)
int ldnalloc = 0;
char * ldn = NULL;
short * dnlx = NULL;
rpmts ts = fsmGetTs(fsm);
security_context_t scon = NULL;
dnlx = (dc ? xcalloc(dc, sizeof(*dnlx)) : NULL);
@ -1240,28 +1234,11 @@ static int fsmMkdirs(FSM_t fsm)
st->st_mode = S_IFDIR | (_dirPerms & 07777);
rc = fsmMkdir(fsm);
if (!rc) {
/* XXX FIXME? only new dir will have context set. */
/* Get file security context from patterns. */
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS) && rpmtsSELabelHandle(ts)) {
if (selabel_lookup_raw(rpmtsSELabelHandle(ts), &scon, fsm->path, st->st_mode) == 0 &&
scon != NULL) {
fsm->fcontext = scon;
rc = fsmLsetfcon(fsm);
}
}
rc = fsmSetSELabel(fsm->sehandle, fsm->path, st->st_mode);
if (fsm->fcontext == NULL)
rpmlog(RPMLOG_DEBUG,
"%s directory created with perms %04o, no context.\n",
"%s directory created with perms %04o\n",
fsm->path, (unsigned)(st->st_mode & 07777));
else {
rpmlog(RPMLOG_DEBUG,
"%s directory created with perms %04o, context %s.\n",
fsm->path, (unsigned)(st->st_mode & 07777),
fsm->fcontext);
freecon(fsm->fcontext);
}
fsm->fcontext = NULL;
}
*te = '/';
}
@ -2003,16 +1980,9 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
}
fsm->opath = _free(fsm->opath);
}
/*
* Set file security context (if not disabled).
*/
/* Set file security context (if enabled) */
if (!rc && !getuid()) {
rc = fsmMapFContext(fsm);
if (!rc) {
rc = fsmLsetfcon(fsm);
freecon(fsm->fcontext);
}
fsm->fcontext = NULL;
rc = fsmSetSELabel(fsm->sehandle, fsm->path, fsm->sb.st_mode);
}
if (S_ISLNK(st->st_mode)) {
if (!rc && !getuid())

View File

@ -146,7 +146,7 @@ struct fsm_s {
const char * dirName; /*!< File directory name. */
const char * baseName; /*!< File base name. */
const unsigned char * digest; /*!< Binary digest (NULL disables). */
security_context_t fcontext;/*!< File security context (NULL disables). */
struct selabel_handle *sehandle; /*!< SELinux label handle (if any). */
void *fcaps; /*!< File capabilities */
pgpHashAlgo digestalgo; /*!< File digest algorithm */