X-Git-Url: https://git.saurik.com/apple/securityd.git/blobdiff_plain/f7aa9f666a1c7ab343b4ce8f1677ea253c4e126e..4cd1cad0dea00daa03e1b54fdf2797a02373ad5b:/src/process.cpp diff --git a/src/process.cpp b/src/process.cpp index 4f482f8..606e949 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -30,6 +30,7 @@ #include "session.h" #include "tempdatabase.h" #include "authority.h" +#include "child.h" // ServerChild (really UnixPlusPlus::Child)::find() #include //@@@ debug only #include "agentquery.h" @@ -38,29 +39,34 @@ // // Construct a Process object. // -Process::Process(Port servicePort, TaskPort taskPort, - const ClientSetupInfo *info, const char *identity, const CommonCriteria::AuditToken &audit) +Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit) : mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid()) { + StLock _(*this); + // set parent session - parent(Session::find(servicePort)); + parent(Session::find(audit.sessionId(), true)); // let's take a look at our wannabe client... if (mTaskPort.pid() != mPid) { - secdebug("SS", "Task/pid setup mismatch pid=%d task=%d(%d) for %s", - mPid, mTaskPort.port(), mTaskPort.pid(), - (identity && identity[0]) ? identity : "(unknown)"); + secdebug("SS", "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()); - secdebug("SS", "New process %p(%d) uid=%d gid=%d session=%p TP=%d %sfor %s", - this, mPid, mUid, mGid, &session(), - mTaskPort.port(), - mByteFlipped ? "FLIP " : "", - (identity && identity[0]) ? identity : "(unknown)"); + // 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(); + + if (SECURITYD_CLIENT_NEW_ENABLED()) + SECURITYD_CLIENT_NEW(this, this->pid(), &this->session(), + (char *)codePath(this->processCode()).c_str(), taskPort, mUid, mGid, mByteFlipped); } @@ -70,35 +76,24 @@ Process::Process(Port servicePort, TaskPort taskPort, // talked to it in the past. This could either be an exec(2), or the client could just // have forgotten all about its securityd client state. Or it could be an attack... // -void Process::reset(Port servicePort, TaskPort taskPort, - const ClientSetupInfo *info, const char *identity, const CommonCriteria::AuditToken &audit) +void Process::reset(TaskPort taskPort, const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit) { - if (servicePort != session().servicePort() || taskPort != mTaskPort) { - secdebug("SS", "Process %p(%d) reset mismatch (sp %d-%d, tp %d-%d) for %s", - this, pid(), servicePort.port(), session().servicePort().port(), taskPort.port(), mTaskPort.port(), - (identity && identity[0]) ? identity : "(unknown)"); - Session &newSession = Session::find(servicePort); - Syslog::alert("Process reset %p(%d) session %d(0x%x:0x%x)->%d(0x%x:0x%x) for %s", - this, pid(), - session().servicePort().port(), &session(), session().attributes(), - newSession.servicePort().port(), &newSession, newSession.attributes(), - (identity && identity[0]) ? identity : "(unknown)"); - //CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); // liar + StLock _(*this); + if (taskPort != mTaskPort) { + secdebug("SS", "Process %p(%d) reset mismatch (tp %d-%d)", + this, pid(), taskPort.port(), mTaskPort.port()); + //@@@ CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); // liar } - - string oldPath = codePath(processCode()); setup(info); - ClientIdentification::setup(this->pid()); - if (codePath(processCode()) == oldPath) { - secdebug("SS", "process %p(%d) path unchanged; assuming client-side reset", this, mPid); + CFCopyRef oldCode = processCode(); + + ClientIdentification::setup(this->pid()); // re-constructs processCode() + if (CFEqual(oldCode, processCode())) { + SECURITYD_CLIENT_RESET_AMNESIA(this); } else { - secdebug("SS", "process %p(%d) path changed; assuming exec with full reset", this, mPid); + SECURITYD_CLIENT_RESET_FULL(this); CodeSigningHost::reset(); } - - secdebug("SS", "process %p(%d) has reset; now %sfor %s", - this, mPid, mByteFlipped ? "FLIP " : "", - (identity && identity[0]) ? identity : "(unknown)"); } @@ -114,7 +109,7 @@ void Process::setup(const ClientSetupInfo *info) pversion = info->version; mByteFlipped = false; } else if (info->order == 0x34120000) { // flip side up - pversion = ntohl(info->version); + pversion = flip(info->version); mByteFlipped = true; } else // non comprende CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION); @@ -130,6 +125,8 @@ void Process::setup(const ClientSetupInfo *info) // Process::~Process() { + SECURITYD_CLIENT_RELEASE(this, this->pid()); + // tell all our authorizations that we're gone IFDEBUG(if (!mAuthorizations.empty()) secdebug("SS", "Process %p(%d) clearing %d authorizations", @@ -141,9 +138,6 @@ Process::~Process() if (auth->endProcess(*this)) delete auth; } - - // no need to lock here; the client process has no more active threads - secdebug("SS", "Process %p(%d) has died", this, mPid); // release our name for the process's task port if (mTaskPort) @@ -168,6 +162,14 @@ Session& Process::session() const } +void Process::checkSession(const audit_token_t &auditToken) +{ + AuditToken audit(auditToken); + if (audit.sessionId() != this->session().sessionId()) + this->changeSession(audit.sessionId()); +} + + LocalDatabase &Process::localStore() { StLock _(*this); @@ -187,12 +189,11 @@ Key *Process::makeTemporaryKey(const CssmKey &key, CSSM_KEYATTR_FLAGS moreAttrib // Change the session of a process. // This is the result of SessionCreate from a known process client. // -void Process::changeSession(Port servicePort) +void Process::changeSession(Session::SessionId sessionId) { // re-parent - parent(Session::find(servicePort)); - - secdebug("SS", "process %p(%d) changed session to %p", this, pid(), &session()); + parent(Session::find(sessionId, true)); + SECURITYD_CLIENT_CHANGE_SESSION(this, &this->session()); }