]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
<rdar://problem/15939788> Improve CUPS sandboxing
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 12 Feb 2014 01:27:42 +0000 (01:27 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 12 Feb 2014 01:27:42 +0000 (01:27 +0000)
Fix a bug in cups-exec where (for some reason) the call to execv was missing...

Update cups-exec to take real options (-u uid, -g gid, -n nice-value) so that
existing applications that use cups-exec won't need changes.  This will also
allow for future changes without breaking things.

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@11578 a1ca3aef-8c08-0410-bb20-df032aa958be

CHANGES.txt
scheduler/cups-exec.c
scheduler/process.c

index a39bbfc81eed067cc74c81cbf08ce7bd808e1416..33442d28ae5f6ea5a9137284c226401cf2662241 100644 (file)
@@ -1,4 +1,4 @@
-CHANGES.txt - 2.0b1 - 2014-01-21
+CHANGES.txt - 2.0b1 - 2014-02-11
 --------------------------------
 
 CHANGES IN CUPS V2.0b1
@@ -13,3 +13,5 @@ CHANGES IN CUPS V2.0b1
          (<rdar://problem/11131245>)
        - cupsRasterInterpretPPD now supports the Orientation header in order to
          support long-edge feed raster printers (<rdar://problem/15837926>)
+       - The filter/backend sandbox on OS X now defaults to a more strict
+         whitelist (<rdar://problem/15939788>)
\ No newline at end of file
index ecbc6bbc64c9e2569ba60dc2515ddcd4c69fe1dd..1111f7d07a8b5af6162eb2edddfbc8bb4b27ac3d 100644 (file)
 #endif /* HAVE_SANDBOX_H */
 
 
+/*
+ * Local functions...
+ */
+
+static void    usage(void) __attribute__((noreturn));
+
+
 /*
  * 'main()' - Apply sandbox profile and execute program.
  */
@@ -42,22 +49,70 @@ int                                 /* O - Exit status */
 main(int  argc,                                /* I - Number of command-line args */
      char *argv[])                     /* I - Command-line arguments */
 {
-  uid_t        uid;                            /* UID */
-  gid_t        gid;                            /* GID */
-  int  niceval;                        /* Nice value */
+  int          i;                      /* Looping var */
+  const char   *opt;                   /* Current option character */
+  uid_t                uid = getuid();         /* UID */
+  gid_t                gid = getgid();         /* GID */
+  int          niceval = 0;            /* Nice value */
 #ifdef HAVE_SANDBOX_H
-  char *sandbox_error = NULL;          /* Sandbox error, if any */
+  char         *sandbox_error = NULL;  /* Sandbox error, if any */
 #endif /* HAVE_SANDBOX_H */
 
 
+ /*
+  * Parse command-line...
+  */
+
+  for (i = 1; i < argc; i ++)
+  {
+    if (argv[i][0] == '-')
+    {
+      for (opt = argv[i] + 1; *opt; opt ++)
+      {
+        switch (*opt)
+        {
+          case 'g' : /* -g gid */
+              i ++;
+              if (i >= argc)
+                usage();
+
+              gid = (gid_t)atoi(argv[i]);
+              break;
+
+          case 'n' : /* -n nice-value */
+              i ++;
+              if (i >= argc)
+                usage();
+
+              niceval = atoi(argv[i]);
+              break;
+
+          case 'u' : /* -g gid */
+              i ++;
+              if (i >= argc)
+                usage();
+
+              uid = (uid_t)atoi(argv[i]);
+              break;
+
+         default :
+             fprintf(stderr, "cups-exec: Unknown option '-%c'.\n", *opt);
+             usage();
+        }
+      }
+    }
+    else
+      break;
+  }
+
  /*
   * Check that we have enough arguments...
   */
 
-  if (argc < 7)
+  if ((i + 3) > argc)
   {
-    puts("Usage: cups-exec /path/to/profile UID GID NICE /path/to/program argv0 argv1 ... argvN");
-    return (1);
+    fputs("cups-exec: Insufficient arguments.\n", stderr);
+    usage();
   }
 
  /*
@@ -71,10 +126,6 @@ main(int  argc,                             /* I - Number of command-line args */
   * Change UID, GID, and nice value...
   */
 
-  uid     = (uid_t)atoi(argv[2]);
-  gid     = (gid_t)atoi(argv[3]);
-  niceval = atoi(argv[4]);
-
   if (uid)
     nice(niceval);
 
@@ -97,8 +148,8 @@ main(int  argc,                              /* I - Number of command-line args */
   * Run in a separate security profile...
   */
 
-  if (strcmp(argv[1], "none") &&
-      sandbox_init(argv[1], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
+  if (strcmp(argv[i], "none") &&
+      sandbox_init(argv[i], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
   {
     cups_file_t        *fp;                    /* File */
     char       line[1024];             /* Line from file */
@@ -108,7 +159,7 @@ main(int  argc,                             /* I - Number of command-line args */
            strerror(errno));
     sandbox_free_error(sandbox_error);
 
-    if ((fp = cupsFileOpen(argv[1], "r")) != NULL)
+    if ((fp = cupsFileOpen(argv[i], "r")) != NULL)
     {
       while (cupsFileGets(fp, line, sizeof(line)))
       {
@@ -122,6 +173,12 @@ main(int  argc,                            /* I - Number of command-line args */
   }
 #endif /* HAVE_SANDBOX_H */
 
+ /*
+  * Execute the program...
+  */
+
+  execv(argv[i + 1], argv + i + 2);
+
  /*
   * If we get here, execv() failed...
   */
@@ -131,6 +188,18 @@ main(int  argc,                            /* I - Number of command-line args */
 }
 
 
+/*
+ * 'usage()' - Show program usage.
+ */
+
+static void
+usage(void)
+{
+  fputs("Usage: cups-exec [-g gid] [-n nice-value] [-u uid] /path/to/profile /path/to/program argv0 argv1 ... argvN\n", stderr);
+  exit(1);
+}
+
+
 /*
  * End of "$Id$".
  */
index 4276dbff4da36eb3c43b387177fa8361e9113c68..6afb5926cfafb9085683f7bea7e54323fcbf272f 100644 (file)
@@ -427,7 +427,7 @@ cupsdStartProcess(
 {
   int          i;                      /* Looping var */
   const char   *exec_path = command;   /* Command to be exec'd */
-  char         *real_argv[107],        /* Real command-line arguments */
+  char         *real_argv[110],        /* Real command-line arguments */
                cups_exec[1024];        /* Path to "cups-exec" program */
   uid_t                user;                   /* Command UID */
   cupsd_proc_t *proc;                  /* New process record */
@@ -514,18 +514,21 @@ cupsdStartProcess(
     snprintf(nice_str, sizeof(nice_str), "%d", FilterNice);
 
     real_argv[0] = cups_exec;
-    real_argv[1] = profile;
-    real_argv[2] = user_str;
-    real_argv[3] = group_str;
+    real_argv[1] = (char *)"-g";
+    real_argv[2] = group_str;
+    real_argv[3] = (char *)"-n";
     real_argv[4] = nice_str;
-    real_argv[5] = (char *)command;
+    real_argv[5] = (char *)"-u";
+    real_argv[6] = user_str;
+    real_argv[7] = profile;
+    real_argv[8] = (char *)command;
 
     for (i = 0;
-         i < (int)(sizeof(real_argv) / sizeof(real_argv[0]) - 7) && argv[i];
+         i < (int)(sizeof(real_argv) / sizeof(real_argv[0]) - 10) && argv[i];
         i ++)
-      real_argv[i + 6] = argv[i];
+      real_argv[i + 9] = argv[i];
 
-    real_argv[i + 6] = NULL;
+    real_argv[i + 9] = NULL;
 
     argv      = real_argv;
     exec_path = cups_exec;