socsvn commit: r254040 - soc2013/dpl/head/contrib/bzip2

dpl at FreeBSD.org dpl at FreeBSD.org
Thu Jul 4 17:20:48 UTC 2013


Author: dpl
Date: Thu Jul  4 17:20:47 2013
New Revision: 254040
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254040

Log:
  Several architectural changes done, there's only setting the right FD capabilities left for bzip2.
  It works transparently without Capsicum.
  Starting with xz in the meanwhile.
  

Modified:
  soc2013/dpl/head/contrib/bzip2/bzip2.c

Modified: soc2013/dpl/head/contrib/bzip2/bzip2.c
==============================================================================
--- soc2013/dpl/head/contrib/bzip2/bzip2.c	Thu Jul  4 15:21:27 2013	(r254039)
+++ soc2013/dpl/head/contrib/bzip2/bzip2.c	Thu Jul  4 17:20:47 2013	(r254040)
@@ -223,7 +223,11 @@
 Int32   workFactor;
 
 #if CAPSICUM
-int capret;
+#define IN_FILENO fileno(outStr)
+#define OUT_FILENO fileno(inStr)
+void limitfd(int);
+FILE  *inStr;
+FILE  *outStr;
 #endif
 
 static void   panic             ( const Char* ) NORETURN;
@@ -237,7 +241,7 @@
 static void   copyFileName ( Char*, Char* );
 static void*   myMalloc    ( Int32 );
 static void   applySavedFileAttrToOutputFile ( IntNative fd );
-
+static void   setExit ( Int32 v );
 
 
 /*---------------------------------------------------*/
@@ -669,6 +673,31 @@
    if (v > exitValue) exitValue = v;
 }
 
+#if CAPSICUM
+/*---------------------------------------------*/
+void
+limitfd(int fd)
+{
+   cap_rights_t rights = 0;
+
+   if (fd == IN_FILENO)
+      rights |= CAP_READ;
+   else if (fd == OUT_FILENO)
+      rights |= CAP_WRITE;
+   else if (fd == STDERR_FILENO)
+      rights |= CAP_WRITE;
+   else
+      abort();
+/*
+   if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS){
+      fprintf ( stderr, "%s: Couldn't limit rights for descriptor %d: %s.\n", 
+         progName, fd, strerror(errno));
+      setExit(1);
+      exit(exitValue);
+   }
+*/
+}
+#endif
 
 /*---------------------------------------------*/
 static 
@@ -1148,12 +1177,14 @@
 static 
 void compress ( Char *name )
 {
+#ifndef CAPSICUM
    FILE  *inStr;
    FILE  *outStr;
-   Int32 n, i;
-#  if CAPSICUM
+#endif
+#if CAPSICUM
    pid_t forkpid;
-#  endif
+#endif
+   Int32 n, i;
    struct MY_STAT statBuf;
 
    deleteOutputOnInterrupt = False;
@@ -1309,7 +1340,7 @@
    }
 
 #  if CAPSICUM
-   /* Pass the limited file descriptors via unix domain socket. */
+   /* Fork and compress in sandbox. */
    if ( (forkpid = fork()) == -1 ){
        fprintf ( stderr, "%s: Couldn't fork: %s.\n", progName, strerror(errno) );
        setExit(1);
@@ -1318,23 +1349,18 @@
       /* Let the children compress */
       wait(NULL);
       return;
-
    } else if (forkpid == 0){
-      capret = cap_rights_limit(fileno(inStr), CAP_READ);
-      capret |= cap_rights_limit(fileno(outStr), CAP_WRITE);
-      
-      if ( capret ){
-         fprintf ( stderr, "%s: Couldn't enter capability mode: %s.\n", 
-            progName, strerror(errno) );
-         setExit(1);
-         exit(exitValue);
-      }
+      limitfd(fileno(inStr));
+      limitfd(fileno(outStr));
+      limitfd(STDERR_FILENO);
+/*
       if (cap_enter() < 0){
          fprintf ( stderr, "%s: Couldn't enter capability mode: %s.\n", 
             progName, strerror(errno) );
          setExit(1);
          exit(exitValue);
       }
+*/
 #     endif
       /*--- Now the input and output handles are sane.  Do the Biz. ---*/
       outputHandleJustInCase = outStr;
@@ -1363,8 +1389,13 @@
 static 
 void uncompress ( Char *name )
 {
+#ifndef CAPSICUM
    FILE  *inStr;
    FILE  *outStr;
+#endif
+#if CAPSICUM
+   pid_t forkpid;
+#endif
    Int32 n, i;
    Bool  magicNumberOK;
    Bool  cantGuess;
@@ -1516,44 +1547,71 @@
      fflush ( stderr );
    }
 
-   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
-   outputHandleJustInCase = outStr;
-   deleteOutputOnInterrupt = True;
-   magicNumberOK = uncompressStream ( inStr, outStr );
-   outputHandleJustInCase = NULL;
-
-   /*--- If there was an I/O error, we won't get here. ---*/
-   if ( magicNumberOK ) {
-     if ( srcMode == SM_F2F ) {
-       applySavedTimeInfoToOutputFile ( outName );
-       deleteOutputOnInterrupt = False;
-       if ( !keepInputFiles ) {
-         IntNative retVal = remove ( inName );
-         ERROR_IF_NOT_ZERO ( retVal );
-       }
-     }
-   } else {
-     unzFailsExist = True;
-     deleteOutputOnInterrupt = False;
-     if ( srcMode == SM_F2F ) {
-       IntNative retVal = remove ( outName );
-       ERROR_IF_NOT_ZERO ( retVal );
-     }
-   }
-   deleteOutputOnInterrupt = False;
 
-   if ( magicNumberOK ) {
-     if (verbosity >= 1)
-       fprintf ( stderr, "done\n" );
-   } else {
-     setExit(2);
-     if (verbosity >= 1)
-       fprintf ( stderr, "not a bzip2 file.\n" ); else
-       fprintf ( stderr,
-               "%s: %s is not a bzip2 file.\n",
-               progName, inName );
+#  if CAPSICUM
+   /* Fork and compress in sandbox. */
+   if ( (forkpid = fork()) == -1 ){
+       fprintf ( stderr, "%s: Couldn't fork: %s.\n", progName, strerror(errno) );
+       setExit(1);
+       exit(exitValue);
+   } else if ( forkpid != 0) {
+      /* Let the children compress */
+      wait(NULL);
+      return;
+   } else if (forkpid == 0){
+      limitfd(fileno(inStr));
+      limitfd(fileno(outStr));
+      limitfd(STDERR_FILENO);
+/*
+      if (cap_enter() < 0){
+         fprintf ( stderr, "%s: Couldn't enter capability mode: %s.\n", 
+            progName, strerror(errno) );
+         setExit(1);
+         exit(exitValue);
+      }
+*/
+#     endif
+      /*--- Now the input and output handles are sane.  Do the Biz. ---*/
+      outputHandleJustInCase = outStr;
+      deleteOutputOnInterrupt = True;
+      magicNumberOK = uncompressStream ( inStr, outStr );
+      outputHandleJustInCase = NULL;
+   
+      /*--- If there was an I/O error, we won't get here. ---*/
+      if ( magicNumberOK ) {
+        if ( srcMode == SM_F2F ) {
+          applySavedTimeInfoToOutputFile ( outName );
+          deleteOutputOnInterrupt = False;
+          if ( !keepInputFiles ) {
+            IntNative retVal = remove ( inName );
+            ERROR_IF_NOT_ZERO ( retVal );
+          }
+        }
+      } else {
+        unzFailsExist = True;
+        deleteOutputOnInterrupt = False;
+        if ( srcMode == SM_F2F ) {
+          IntNative retVal = remove ( outName );
+          ERROR_IF_NOT_ZERO ( retVal );
+        }
+      }
+      deleteOutputOnInterrupt = False;
+   
+      if ( magicNumberOK ) {
+        if (verbosity >= 1)
+          fprintf ( stderr, "done\n" );
+      } else {
+        setExit(2);
+        if (verbosity >= 1)
+          fprintf ( stderr, "not a bzip2 file.\n" ); else
+          fprintf ( stderr,
+                  "%s: %s is not a bzip2 file.\n",
+                  progName, inName );
+      }
+#     if CAPSICUM
+      exit(0);
    }
-
+#  endif
 }
 
 


More information about the svn-soc-all mailing list