]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_authorization/lib/trampolineClient.cpp
Security-58286.20.16.tar.gz
[apple/security.git] / OSX / libsecurity_authorization / lib / trampolineClient.cpp
index dfbc986fef3b15b505eab39d95fe035e7df85bac..672768f56412b489571d04a143d740a417cf90c0 100644 (file)
@@ -100,22 +100,8 @@ OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExter
        if (flags != 0)
                return errAuthorizationInvalidFlags;
 
-    // create the mailbox file
-    FILE *mbox = tmpfile();
-    if (!mbox)
-        return errAuthorizationInternal;
-    if (fwrite(extForm, sizeof(*extForm), 1, mbox) != 1) {
-        fclose(mbox);
-        return errAuthorizationInternal;
-    }
-    fflush(mbox);
-    
        // compute the argument vector here because we can't allocate memory once we fork.
 
-    // make text representation of the temp-file descriptor
-    char mboxFdText[20];
-    snprintf(mboxFdText, sizeof(mboxFdText), "auth %d", fileno(mbox));
-
        // where is the trampoline?
 #if defined(NDEBUG)
        const char *trampoline = TRAMPOLINE;
@@ -125,12 +111,26 @@ OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExter
                trampoline = TRAMPOLINE;
 #endif //NDEBUG
 
-       const char **argv = argVector(trampoline, pathToTool, mboxFdText, arguments);
+       // make a data exchange pipe
+       int dataPipe[2];
+       if (pipe(dataPipe)) {
+               secinfo("authexec", "data pipe failure");
+               return errAuthorizationToolExecuteFailure;
+       }
+
+       // make text representation of the pipe handle
+       char pipeFdText[20];
+       snprintf(pipeFdText, sizeof(pipeFdText), "auth %d", dataPipe[READ]);
+       const char **argv = argVector(trampoline, pathToTool, pipeFdText, arguments);
        
        // make a notifier pipe
        int notify[2];
        if (pipe(notify)) {
-        fclose(mbox);
+               close(dataPipe[READ]); close(dataPipe[WRITE]);
+        if(argv) {
+                       free(argv);
+               }
+               secinfo("authexec", "notify pipe failure");
                return errAuthorizationToolExecuteFailure;
     }
 
@@ -138,7 +138,11 @@ OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExter
        int comm[2];
        if (communicationsPipe && socketpair(AF_UNIX, SOCK_STREAM, 0, comm)) {
                close(notify[READ]); close(notify[WRITE]);
-        fclose(mbox);
+               close(dataPipe[READ]); close(dataPipe[WRITE]);
+        if(argv) {
+                       free(argv);
+               }
+               secinfo("authexec", "comm pipe failure");
                return errAuthorizationToolExecuteFailure;
        }
 
@@ -159,17 +163,28 @@ OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExter
                        }
                        secinfo("authexec", "fork failed (errno=%d)", errno);
                        close(notify[READ]); close(notify[WRITE]);
-                       return errAuthorizationToolExecuteFailure;
+                       status = errAuthorizationToolExecuteFailure;
+            goto exit_point;
 
                default: {      // parent
                        // close foreign side of pipes
                        close(notify[WRITE]);
                        if (communicationsPipe)
                                close(comm[WRITE]);
-                
-            // close mailbox file (child has it open now)
-            fclose(mbox);
-                       
+
+                       close(dataPipe[READ]);
+                       if (write(dataPipe[WRITE], extForm, sizeof(*extForm)) != sizeof(*extForm)) {
+                               secinfo("authexec", "fwrite data failed (errno=%d)", errno);
+                               status = errAuthorizationInternal;
+                               close(notify[READ]);
+                               close(dataPipe[WRITE]);
+                               if (communicationsPipe) {
+                                       close(comm[READ]);
+                                       close(comm[WRITE]);
+                               }
+                               goto exit_point;
+                       }
+                       close(dataPipe[WRITE]);
                        // get status notification from child
                        secinfo("authexec", "parent waiting for status");
                        ssize_t rc = read(notify[READ], &status, sizeof(status));
@@ -182,10 +197,15 @@ OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExter
                        case sizeof(status):    // read succeeded: child reported an error
                                secinfo("authexec", "parent received status=%d", (int)status);
                                close(notify[READ]);
-                               if (communicationsPipe) { close(comm[READ]); close(comm[WRITE]); }
+                               close(dataPipe[WRITE]);
+                               if (communicationsPipe) {
+                                       close(comm[READ]);
+                                       close(comm[WRITE]);
+                               }
                                goto exit_point;
                        case 0:                                 // end of file: exec succeeded
                                close(notify[READ]);
+                               close(dataPipe[WRITE]);
                                if (communicationsPipe)
                                        *communicationsPipe = fdopen(comm[READ], "r+");
                                secinfo("authexec", "parent resumes (no error)");
@@ -199,7 +219,10 @@ OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExter
                        close(notify[READ]);
                        if (communicationsPipe)
                                close(comm[READ]);
-                       
+
+                       // close write end of the data PIPE
+                       close(dataPipe[WRITE]);
+
                        // fd 1 (stdout) holds the notify write end
                        dup2(notify[WRITE], 1);
                        close(notify[WRITE]);
@@ -219,6 +242,9 @@ OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExter
 
                        // execute failed - tell the parent
                        {
+                               // in case of failure, close read end of the data pipe as well
+                               close(dataPipe[WRITE]);
+                               close(dataPipe[READ]);
                                OSStatus error = errAuthorizationToolExecuteFailure;
                                error = h2n(error);
                                write(1, &error, sizeof(error));