Sanitize selinux labeling in fsm
authorPanu Matilainen <pmatilai@redhat.com>
Fri, 13 Jan 2012 09:08:47 +0000 (11:08 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Fri, 13 Jan 2012 09:08:47 +0000 (11:08 +0200)
- 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.

lib/fsm.c
lib/fsm.h

index 0b9e0bd..0b4cd8b 100644 (file)
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -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;
        }
+
+       freecon(scon);
     }
-    return 0;
+#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",
+                   rpmlog(RPMLOG_DEBUG,
+                           "%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())
index 963b5aa..331520d 100644 (file)
--- a/lib/fsm.h
+++ b/lib/fsm.h
@@ -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 */