android IPC通信中的UID和PID識別 – Android移動開發技術文章_手機開發 Android移動開發教學課程

 

 

IPCThreadState對象維護瞭2個變量

 

            pid_t               mCallingPid;

 

            uid_t               mCallingUid;

 

    從變量名稱來看,這2個變量保存瞭進程的PID和UID,並且由於這兩個變量由IPCThreadState對象維護,可見它們是與IPC相關的。具體它們保存的是IPC發送方的PID和UID還是當前進程的IPD和UID,視情況而定。

 

    在IPC調用過程中,被調用方需要知道調用方的UID和PID,以便被調用方用於權限檢測;所以需要一種方式來提供調用方的UID和PID,因此上述2個變量的主要作用就是用於權限檢測。

 

    那麼我們想象一下,下面描述的情況下,mCallingPid和mCallingUid又應該保存誰的UID和PID?假如有2個進程process A和process B,我們站在process B的角度來分析,process A IPC調用process B, 而process B 又調用同樣處於process B的Service的接口(盡管此時實際上不是遠程調用,並且開發者是知道的,但是對於Binder調用機制來說,它本身並不知道當前的調用是否為遠程調用,前幾篇文章中有分析系統如何確定是否為遠程調用,這個過程是在binder driver中實現的),那麼此時mCallingPid和mCallingUid是不是應該保存process B的UID和PID?

 

1.       process B在被process A IPC調用時, process B需知道process A的UID和PID,來檢查process A的訪問權限,此時mCallingUid和mCallingPid保存的是process A的UID和PID。

 

2.       在IPC遠程調用process B的過程中,process B的方法調用瞭同進程中的service的接口,process B既是調用方也是被調用方,雖然這個過程比較無聊,但是鑒於IPC過程的不透明性,因此process B仍然需要進行權限檢測。

 

 

    前面的文章中分析過,binder driver會判斷當前的Binder調用是否為遠程調用,如果是同進程調用的話,BD就不會再向應用提供進程的PID和UID。因此在process B中需要顯示的設置當前的PID和UID。

 

    為實現以上case,android提供瞭一組函數

 

    public static final native long clearCallingIdentity();

 

    public static final native void restoreCallingIdentity(long token);

 

    process B的方法調用瞭同進程中的service的接口前,clearCallingIdentity()方法會清除process A的UID和PID,重置為process B的UID和PID。

 

    process B的方法調用瞭同進程中的service的接口後,此時仍然處在process A遠程調用process B方法的過程中,此時需要restore  process A的UID和PID。

 

    本文描述的case,雖然在application 開發中並不常見,但是在system_server中很常見,比如client調用ActivityManagerService的方法,而ActivityManagerService又調用瞭PackageManagerService的方法,並且ActivityManagerService和PackageManagerService均會運行在system_server進程中。

 

摘自 杜文濤的專欄

發佈留言