【Android源碼】 權限驗證分析(一)

做Android多年總是有種雲山霧裏的感覺,說懂,其實你不懂,也知道自己還沒懂。說不懂,你又能支支吾吾說個三四,生活中我們也有很多這種一知半解的情況。因爲自己沒有去深入鑽研,在工作中大多都是拿來主義,過後又沒有去深入瞭解個所以然,久而久之你知道的永遠都只是一些皮毛,也就談不上進步。

不積跬步,無以至千里,養成總結記錄的好習慣,有時間多看看Android的源碼,逐段代碼的分析理解,相信不久後就能對別人說我是真的懂Android。

後續我將一點點記錄自己看源碼的過程,做個記錄,增強理解,一起學習,共同進步。

我給自己定的路子是先花時間深入研究一下Android的整個權限機制,也是Android最讓人頭疼的安全性。

相信很多人都看到過下面這段的代碼,那這段代碼到底有什麼作用呢?。。。往後看你就會知道這處的代碼在整個Android中有多重要了

Java代碼  
final long token = Binder.clearCallingIdentity();
try {
     ...//邏輯代碼
} finally {
     Binder.restoreCallingIdentity(token);
}
C++代碼

//獲取遠程Binder調用端的pid
pid_t IPCThreadState::getCallingPid() const
{
    return mCallingPid;
}

//獲取遠程Binder調用端的uid
uid_t IPCThreadState::getCallingUid() const
{
    return mCallingUid;
}

//清空遠程端Binder調用的uid和pid,賦值爲本地端的pid和uid
int64_t IPCThreadState::clearCallingIdentity()
{
    int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
    clearCaller();
    return token;
}

void IPCThreadState::clearCaller()
{
    mCallingPid = getpid(); //當前進程pid賦值給mCallingPid
    mCallingUid = getuid(); //當前進程uid賦值給mCallingUid
}

//恢復遠程端Binder調用的uid和pid
void IPCThreadState::restoreCallingIdentity(int64_t token)
{
    mCallingUid = (int)(token>>32);
    mCallingPid = (int)token;
}

在執行代碼邏輯之前調用clearCallingIdentity設置爲本地uid和pid,並且保存遠端調用的uid和pid,返回token,高32位存儲uid,低32位存儲pid,代碼執行完畢後又調用restoreCallingIdentity恢復遠端的值,token逆向位移運算。

一句話總結:restoreCallingIdentity作用是恢復遠程調用端的uid和pid信息,正好是`clearCallingIdentity`的反過程;

說了這麼多,那麼他到底爲什麼重要呢,舉個例子來說明,就會明白了

場景分析:

  1. 線程A通過Binder遠程調用線程B:則線程B的IPCThreadState中的mCallingUid和mCallingPid保存的就是線程A的UID和PID。這時在線程B中調用Binder.getCallingPid()和Binder.getCallingUid()方法便可獲取線程A的UID和PID,然後利用UID和PID進行權限比對,判斷線程A是否有權限調用線程B的某個方法。
  2. 線程B通過Binder調用當前線程的某個組件:此時線程B是線程B某個組件的調用端,則mCallingUid和mCallingPid應該保存當前線程B的PID和UID,故需要調用clearCallingIdentity()方法完成這個功能。當線程B調用完某個組件,由於線程B仍然處於線程A的被調用端,因此mCallingUid和mCallingPid需要恢復成線程A的UID和PID,這是調用restoreCallingIdentity()即可完成。

一句話總結:每個線程都可以是別人的中間者,調用你的人改變了你的角色賦予你某些權力,去實現某個目的,目的達到後你要恢復自己本來角色(這是你的義務),否者你將失去自我,給整個系統帶來安全隱患。

 

Android源碼 權限驗證分析(二)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章