X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/6b200bc335dc93c5516ccb52f14bd896d8c7fad7..dd5fb164cf5b32c462296bc65e289e100f74b59a:/OSX/libsecurity_authorization/lib/trampolineClient.cpp diff --git a/OSX/libsecurity_authorization/lib/trampolineClient.cpp b/OSX/libsecurity_authorization/lib/trampolineClient.cpp index dfbc986f..672768f5 100644 --- a/OSX/libsecurity_authorization/lib/trampolineClient.cpp +++ b/OSX/libsecurity_authorization/lib/trampolineClient.cpp @@ -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));