]> git.saurik.com Git - apple/securityd.git/blobdiff - src/process.cpp
securityd-55199.3.tar.gz
[apple/securityd.git] / src / process.cpp
index 4f482f8edf31a584488abd01cef8c52ad1d54c38..606e9498df462f995b6acac660ee41c9d05a6a61 100644 (file)
@@ -30,6 +30,7 @@
 #include "session.h"
 #include "tempdatabase.h"
 #include "authority.h"
 #include "session.h"
 #include "tempdatabase.h"
 #include "authority.h"
+#include "child.h"          // ServerChild (really UnixPlusPlus::Child)::find()
 
 #include <security_utilities/logging.h>        //@@@ debug only
 #include "agentquery.h"
 
 #include <security_utilities/logging.h>        //@@@ debug only
 #include "agentquery.h"
 //
 // Construct a Process object.
 //
 //
 // 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())
 {
  :  mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid())
 {
+       StLock<Mutex> _(*this);
+       
        // set parent session
        // 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) {
 
     // 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());
 
                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<ServerChild>(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...
 //
 // 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<Mutex> _(*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);
        setup(info);
-       ClientIdentification::setup(this->pid());
-       if (codePath(processCode()) == oldPath) {
-               secdebug("SS", "process %p(%d) path unchanged; assuming client-side reset", this, mPid);
+       CFCopyRef<SecCodeRef> oldCode = processCode();
+
+       ClientIdentification::setup(this->pid());       // re-constructs processCode()
+       if (CFEqual(oldCode, processCode())) {
+               SECURITYD_CLIENT_RESET_AMNESIA(this);
        } else {
        } else {
-               secdebug("SS", "process %p(%d) path changed; assuming exec with full reset", this, mPid);
+               SECURITYD_CLIENT_RESET_FULL(this);
                CodeSigningHost::reset();
        }
                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 = 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);
                mByteFlipped = true;
        } else // non comprende
                CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
@@ -130,6 +125,8 @@ void Process::setup(const ClientSetupInfo *info)
 //
 Process::~Process()
 {
 //
 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", 
        // 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;
     }
                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)
        
     // 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<Mutex> _(*this);
 LocalDatabase &Process::localStore()
 {
        StLock<Mutex> _(*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.
 //
 // 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
 {
        // 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());
 }
 
 
 }