3.3.1 IPC鉤子函數設計與實現
IPC Binder是Android最重要的處理序間通訊機制,因此,必須在此實施強制存取控制。
1. 修改secuirty.h
開啟終端shell,輸入指令“cd /android4.0/kernel/goldfish/include/linux/vim security.h”,找到結構security_operations,加入函數指標變數,如下所示:
/*
* This is the main security structure.
*/
struct security_operations {
charname[SECURITY_NAME_MAX + 1];
#ifdef HAVE_SMACK
/*
* to add a binder hook
* */
int(*binder_transaction) (struct task_struct *from, struct task_struct *to);
#endif
隨後在security_operations定義結尾後,加入函式宣告,如下:
#ifdef HAVE_SMACK
int security_binder_transaction(structtask_struct *from, struct task_struct *to);
#endif
在LSM鉤子函數實現處加入security_binder_transaction的定義,如下:
#ifdef HAVE_SMACK
static inline intsecurity_binder_transaction(struct task_struct *from, struct task_struct *to) {
return 0;
}
#endif
2. 修改security.c
開啟終端shell,輸入指令“cd /android4.0/kernel/goldfish/security/vim security.c”,加入函數,如下所示:
#ifdefHAVE_SMACK
intsecurity_binder_transaction(struct task_struct *from, struct task_struct *to) {
returnsecurity_ops->binder_transaction(from, to);
}
#endif
3. 修改smack_lsm.c
開啟終端shell,輸入指令“cd /android4.0/kernel/goldfish/security/smack/vim smack_lsm.c”,加入函數“smack_binder_transaction”,如下所示:
#ifdefHAVE_SMACK
/*
* smack_binder_transaction - to check bindertransaction between two tasks
* */
static intsmack_binder_transaction(struct task_struct *from, struct task_struct *to) {
int rc1, rc2;
/*
* ask the two task must have writepermission to each other
* */
rc1 = smk_access(task_security(from),task_security(to), MAY_WRITE);
rc2 = smk_access(task_security(to),task_security(from), MAY_WRITE);
return rc1 == 0 && rc2 == 0 ? 0:1;
}
#endif
此鉤子函數用來判斷源進程from和目標進程to之間有沒有互相寫入權限。最後在結構體security_operations smack_ops新增成員變數如下:
structsecurity_operations smack_ops = {
.name = "smack",
#ifdefHAVE_SMACK
.binder_transaction = smack_binder_transaction,
#endif
4. 重新編譯模擬器核心
編譯Android核心方法已經在第二章有所闡述,這裡不再敘述。
3.3.2
每個進程分為使用者空間和核心空間兩部分,不同進程的使用者空間是無法共用的,進程核心空間通過Android Binder來實現IPC。Binder驅動代碼位於“/android4.0/kernel/goldfish/driver/staging/android/bind.c”檔案中,其中binder_transaction函數使用binder_transaction_data結構體的資料來執行Binder定址、複製Binder IPC資料、產生及檢索Binder節點等操作。開啟終端shell,輸入指令“cd
/host/android4.0/kernel/goldfish/drivers/staging/android/vim binder.c”,找到該函數的定義,如下
static voidbinder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply);
在源進程和目標進程確定後,加入代碼,如下:
if(security_binder_transaction(proc->tsk,target_proc->tsk)) {
return_error = BR_FAILED_REPLY;
goto err_invalid_target_handle;
}
其中,target_proc->tsk指向目標進程的task_struct,proc->tsk指向源進程的task_struct,加入security_task_movememory用來判斷當前進程對源進程有沒有寫入權限,security_binder_transaction用來判斷源進程對目標進程有沒有寫入權限,這兩個函數均為LSM鉤子函數,由於核心已經裝載了smack模組,因此它們是指向了smack核心的smack_task_movememory和smack_binder_transaction。加入上述代碼的目的是為了防止進程不經授權濫用IPC
Binder進行通訊,正如所示:
如所示,服務用戶端通過Binder調用Service Server的foo函數,服務用戶端將Binder IPC資料通過BinderDriver傳遞給Service Server,Binder Driver是源進程和目標進程通訊的媒介,IPC檢查機制就是在Binder Driver中檢查源進程和目標進程之間有沒有互相“寫”的許可權。在進程的安全性標籤不是“_”的前提下,使用Smack可以實現對進程的控制。例如上層應用如果要想實現發簡訊的功能,與上層應用所對應的Linux進程是在BinderDriver中與radio進程進行互相通訊,如果smack規則否定了上層應用對radio“寫”許可權,那麼上層應用不能實現發簡訊的功能。再如,上層應用要想實現訪問通訊錄的目的,上層應用也是在Binder
Driver中與通訊錄進程進行通訊,如果smack規則容許上層應用對通訊錄進程有“寫”的許可權,那麼上層應用才可以訪問通訊錄。惡意軟體可能繞過Android架構層的許可權檢查機制,但它們繞不過核心的IPC檢查。