X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb..7e6b461318c8a779d91381531435a68ee4e8b6ed:/securityd/src/process.cpp?ds=sidebyside diff --git a/securityd/src/process.cpp b/securityd/src/process.cpp index c756c6b7..9ab05df8 100644 --- a/securityd/src/process.cpp +++ b/securityd/src/process.cpp @@ -29,9 +29,9 @@ #include "server.h" #include "session.h" #include "tempdatabase.h" -#include "authority.h" #include "child.h" // ServerChild (really UnixPlusPlus::Child)::find() +#include #include //@@@ debug only #include "agentquery.h" @@ -40,33 +40,44 @@ // Construct a Process object. // Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit) - : mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid()) + : mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid()), mAudit(audit) { StLock _(*this); - + xpc_transaction_begin(); // set parent session parent(Session::find(audit.sessionId(), true)); - - // let's take a look at our wannabe client... + + // let's take a look at our wannabe client... + + // Not enough to make sure we will get the right process, as + // pids get recycled. But we will later create the actual SecCode using + // the audit token, which is unique to the one instance of the process, + // so this just catches a pid mismatch early. if (mTaskPort.pid() != mPid) { - secdebug("SS", "Task/pid setup mismatch pid=%d task=%d(%d)", - mPid, mTaskPort.port(), mTaskPort.pid()); + secnotice("SecServer", "Task/pid setup mismatch pid=%d task=%d(%d)", + mPid, mTaskPort.port(), mTaskPort.pid()); CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED); // you lied! } - + setup(info); - ClientIdentification::setup(this->pid()); - + ClientIdentification::setup(this->audit_token()); + + if(!processCode()) { + // This can happen if the process died in the meantime. + secnotice("SecServer", "no process created in setup, old pid=%d old task=%d(%d)", + mPid, mTaskPort.port(), mTaskPort.pid()); + CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED); + } + // NB: ServerChild::find() should only be used to determine // *existence*. Don't use the returned Child object for anything else, // as it is not protected against its underlying process's destruction. if (this->pid() == getpid() // called ourselves (through some API). Do NOT record this as a "dirty" transaction || ServerChild::find(this->pid())) // securityd's child; do not mark this txn dirty - VProc::Transaction::deactivate(); + xpc_transaction_end(); - if (SECURITYD_CLIENT_NEW_ENABLED()) - SECURITYD_CLIENT_NEW(this, this->pid(), &this->session(), - (char *)codePath(this->processCode()).c_str(), taskPort, mUid, mGid, mByteFlipped); + secinfo("SecServer", "%p client new: pid:%d session:%d %s taskPort:%d uid:%d gid:%d", this, this->pid(), this->session().sessionId(), + (char *)codePath(this->processCode()).c_str(), taskPort.port(), mUid, mGid); } @@ -80,19 +91,18 @@ void Process::reset(TaskPort taskPort, const ClientSetupInfo *info, const Common { StLock _(*this); if (taskPort != mTaskPort) { - secdebug("SS", "Process %p(%d) reset mismatch (tp %d-%d)", + secnotice("SecServer", "Process %p(%d) reset mismatch (tp %d-%d)", this, pid(), taskPort.port(), mTaskPort.port()); //@@@ CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); // liar } setup(info); CFCopyRef oldCode = processCode(); - ClientIdentification::setup(this->pid()); // re-constructs processCode() + ClientIdentification::setup(this->audit_token()); // re-constructs processCode() if (CFEqual(oldCode, processCode())) { - SECURITYD_CLIENT_RESET_AMNESIA(this); + secnotice("SecServer", "%p Client reset amnesia", this); } else { - SECURITYD_CLIENT_RESET_FULL(this); - CodeSigningHost::reset(); + secnotice("SecServer", "%p Client reset full", this); } } @@ -125,23 +135,13 @@ void Process::setup(const ClientSetupInfo *info) // Process::~Process() { - SECURITYD_CLIENT_RELEASE(this, this->pid()); + secinfo("SecServer", "%p client release: %d", this, this->pid()); - // tell all our authorizations that we're gone - IFDEBUG(if (!mAuthorizations.empty()) - secdebug("SS", "Process %p(%d) clearing %d authorizations", - this, mPid, int(mAuthorizations.size()))); - for (AuthorizationSet::iterator it = mAuthorizations.begin(); - it != mAuthorizations.end(); ) { - AuthorizationToken *auth = *it; - while (++it != mAuthorizations.end() && *it == auth) ; // Skip duplicates - if (auth->endProcess(*this)) - delete auth; - } - // release our name for the process's task port - if (mTaskPort) - mTaskPort.destroy(); + if (mTaskPort) { + mTaskPort.deallocate(); + } + xpc_transaction_end(); } void Process::kill() @@ -164,7 +164,7 @@ Session& Process::session() const void Process::checkSession(const audit_token_t &auditToken) { - AuditToken audit(auditToken); + Security::CommonCriteria::AuditToken audit(auditToken); if (audit.sessionId() != this->session().sessionId()) this->changeSession(audit.sessionId()); } @@ -193,49 +193,7 @@ void Process::changeSession(Session::SessionId sessionId) { // re-parent parent(Session::find(sessionId, true)); - SECURITYD_CLIENT_CHANGE_SESSION(this, &this->session()); -} - - -// -// Authorization set maintainance -// -void Process::addAuthorization(AuthorizationToken *auth) -{ - assert(auth); - StLock _(*this); - mAuthorizations.insert(auth); - auth->addProcess(*this); -} - -void Process::checkAuthorization(AuthorizationToken *auth) -{ - assert(auth); - StLock _(*this); - if (mAuthorizations.find(auth) == mAuthorizations.end()) - MacOSError::throwMe(errAuthorizationInvalidRef); -} - -bool Process::removeAuthorization(AuthorizationToken *auth) -{ - assert(auth); - StLock _(*this); - // we do everything with a single set lookup call... - typedef AuthorizationSet::iterator Iter; - Iter it = mAuthorizations.lower_bound(auth); - bool isLast; - if (it == mAuthorizations.end() || auth != *it) { - isLast = true; - } else { - Iter next = it; ++next; // following element - isLast = (next == mAuthorizations.end()) || auth != *next; - mAuthorizations.erase(it); // remove first match - } - if (isLast) { - if (auth->endProcess(*this)) // ... tell it to remove us, - return true; // ... and tell the caller - } - return false; // keep the auth; it's still in use + secnotice("SecServer", "%p client change session to %d", this, this->session().sessionId()); } @@ -251,7 +209,6 @@ void Process::dumpNode() Debug::dump(" FLIPPED"); Debug::dump(" task=%d pid=%d uid/gid=%d/%d", mTaskPort.port(), mPid, mUid, mGid); - CodeSigningHost::dump(); ClientIdentification::dump(); }