Linux安全模組

Linux安全模組

Linux安全模組(Linux Secrity Module,簡稱LSM)是一種輕量級通用訪問控制框架,適合於多種訪問控制模型在它上面以核心可載入模組的形實現。用戶可以根據自己的需求選擇合適的安全模組載入到核心上實現。

基本介紹

  • 中文名:Linux安全模組
  • 外文名:Linux Security Modules
  • 學科:計算機科學
  • 機制:安全域、hook函式等
  • 定義:輕量級通用訪問控制框架
  • 套用:Linux系統
基本原理,實現機制,安全域,hook函式調用,安全模組載入與卸載,安全系統調用,Capabilities機制,

基本原理

LSM的產生是具有其歷史原因的。隨著分散式信息系統的發展和套用業務的日益複雜,信息系統的安全需求也趨於多樣化。現有的安全策略往往是針對特定的安全需求而設計的,因此單一的安全策略越來越難以滿足信息系統安全需求。在這種情況下,允許各種安全策略同時存在於系統內並發揮安全作用的安全框架成為研究重點。GFAC、Flask等安全框架由於出現較早,且有專門的研究機構對其進行研究,目前已有如RSBAC、SELinux等較為成熟的套用。但由於二者對核心影響相對較大,且未形成統一標準,因此並未融入主流作業系統。
2001年,在Linux核心2.5高峰會議上,Linux創始人Linus Torvalds提出Linux核心需要自己的通用訪問框架,並建議以核心模組的方式來實施各種安全策略。回響Linus號召Chris Wright等人完成了LSM的設計開發工作,並與2002年4月28日以程式補丁的形式對外公布。2003年,LSM正式成為核心組成部分,隨核心2.6發行。LSM作為輕量級、通用的訪問控制框架,具有以下特點:
  1. 真正通用,使得採用不同的安全模型僅僅是載入不同的核心模組;
  2. 概念簡單、高效,而且對核心衝擊較小;
  3. 支持現有的POSIX.1e的capabilities邏輯,將其作為一種可選安全模組。
作為通用訪問控制框架,LSM本身並不提供任何的安全策略,而是為各種安全策略提供了通用的框架。安全策略以安全模組的形式實現,並加通過LSM載入進入系統,為系統提供安全保障。為此保證此目的,LSM對系統核心做了如下修改:
  1. 為核心關鍵數據結構增加安全域欄位,用以關聯安全信息;
  2. 在關鍵系統調用之前插入hook函式,對訪問進行判斷;
  3. 提供模組註冊與卸載函式,用於安全模組的載入與卸載;
  4. 提供通用的安全系統調用接口,用以安全系統調用的擴展;
  5. 部分分離capabilities機制,將其作為獨立的安全模組。
安全模組通過模組註冊函式載入進入LSM,對核心關鍵資源設定安全信息,並將自己的安全策略函式與LSM的hook函式進行關聯。用戶進程提出系統資源訪問訪問請求,轉入核心空間,並做傳統的Linux系統DAC(Discretionary Access Control)判斷。之後,LSM調用hook函式,該hook函式以指針的形式與特定安全模組的安全策略函式關聯,用以判斷對該對象的訪問是否符合安全策略,從而進行訪問控制。LSM基本原理如圖所示。
Linux安全模組

實現機制

安全域

LSM在核心關鍵數據結構添加了安全域欄位。該欄位由具體的安全模組設定管理,存儲著核心關鍵數據結構的安全信息。安全信息是系統資源的標識,是多數訪問控制策略實現其安全機制的重要信息。不同的安全策略,所針對的安全問題不同,其關注的客體安全信息也不同。因此,LSM沒有在核心中添加特定的安全信息,而是為核心添加了透明安全域(Opaque Security Fields),以保證其通用性。
安全域欄位是一個空類型的指針,特定安全模組載入後,該指針所指向的數據空間存儲著核心數據結構的安全信息。該安全信息是由具體的安全模組設定和管理的,不受LSM框架的影響。如此,便可以保證LSM對多種安全模組的通用性。但是,安全域欄位無法同時指向兩個及兩個以上安全模組對核心設定的安全信息,這也正是本課題擬解決的問題之一。
LSM為安全模組提供了設定和管理核心數據結構安全域欄位的hook函式接口。安全模組只需要實現這些函式,便可以靈活對核心數據結構的安全信息進行設定和管理。例如,LSM提供了alloc_security和frce_security函式用於申請和釋放安全信息空間,提供了post_lookup函式用於對inode查詢之後修改安全信息。
以SELinux的file結構為例,LSM為核心數據結構file增添了透明的安全域欄位,該欄位指向SELinux對file結構設定的安全信息。修改後的file結構如下:
struct file{……    void* f-security;/*空類型指針f-security*/    ……};
SELinux對file結構設定的安全信息如下:
struct file_security_struct{    u32 sid;    u32 fown—sid;    u32 isid;    u32 pseqno;};
SELinux設定file結構的安全信息,並file安全域關聯:
static int filc_alloc_security(struct file *file){……    struct file_security_struct *fsec;    fsec=kzalloc(sizeof(struct1File_security_struct),GFP_KERNEL);    if(!fSec)    return -NNOMEM;    file->f_security=fSec;/*將指針f-security與安全數據fcsc關聯*/……}
SELinux撤銷file結構的安全信息,一般發生在SELinux模組從LSM卸載時:
static void file_free_security(struct file *file){    struct file_security_struct *fsec=file->f_security;    file一>f_security=NULL;    kfree(fSec);}
可見,對核心安全域欄位的定義及管理都是由具體的安全模組實現,這便保證了LSM框架的高通用性。LSM為核心的9個關鍵數據結添加了安全域欄位,如表所示。
Linux安全模組

hook函式調用

LSM在執行對核心關鍵資源訪問之前,插入對hook函式的調用。這些hook函式從功能上講,大致可分成兩類:
  • 用於管理核心對象安全域的hook函式
  • 用以執行訪問控制的hook函式。
前文所提到的alloc_security,free_security和post_lookup函式都屬於第一類hook函式。而如控制創建和刪除目錄的inode_mkdir和inode_rmdir等hook函式則屬於第二類。所有的hook函式都是由具體的安全模組根據其自身的安全策略實現的。安全模組載入後,LSM框架的鉤子函式表security_ops將與安全模組實現的hook函式關聯。在執行對系統關鍵資源訪問之前,LSM將通過security_ops調用安全模組的hook函式對。訪問行為進行安全控制,此時調用的hook函式一般屬於第二類。第二類hook函式的返回值一般為整數,若為0,則表示安全模組允許對核心對象的訪問;否則,表示拒絕訪問。
security_ops是struct security_operations類型的結構體,該結構內的函式指針指向安全模組的hook函式。LSM通過secu“tyops.>functionname來實現對安全模組hook函式的調用。LSM在核心中插入了160個hook函式。根據所針對的核心對象不同,這些h00k函式可以分為七類:進程、程式載入、IPC、檔案及檔案系統、網路、Linux動態載入模組及一個系統hook函式類。這些hook函式通過security-ops結構組織起來並調用。security-ops的結構如下:
struct security_operations{        ……/*其它hook函式*/      int(*inode_create)(struct inode*dir,struct dentry*dentry,int mode);/*檢驗創建普通檔案許可權*/    int(*task_create)(unsigned long clone_flags);/*檢驗創建子進程許可權*/    int(*socket_create)(int family'int type,int protocol,int kern);/*檢驗創建新socket許可權*/    int(*ipc_permission)(struct kern_ipc_pem*ipcp,short flag);/*檢驗訪問IPC許可權*/ };
安全模組只需要對security-ops所引用的hook函式進行實現,便可以發揮訪問控制功能。所針對的安全問題不同,不同的安全模組實現的hook函式的種類、數量和方式也可以不同。SELinux安全模組對幾乎全部的hook函式做了實現,而LSM自帶的默認的dummy安全模組對任何的hook函式只是簡單的返回零值,不做任何安全檢測。
綜上,LSM框架可以通過hook函式調用安全模組對系統訪問實施訪問控制,同時,為安全模組提供了統一的函式接口,使安全模組的設計更加靈活和獨立。

安全模組載入與卸載

安全模組需要先向LSM註冊,通過後載入進入系統,其實現的鉤子函式才能夠被LSM調用,發揮安全作用。在系統核心引導時,LSM默認載入dummy安全模組。Dummy安全模組對全部的鉤子函式不做任何實現,僅僅是返回允許系統訪問的零值。
除dummy之外的安全模組載入卸載時,需要調用模組載入與卸載函式。LSM提供了兩對函式以完成安全模組的載入和卸載:
int register_security(struct security_operations *security_ops)int unregister_security(struct security_operations *security_ops)int mod_reg_security(const char *name,struct security_operations *ops)int mod_unreg_security(const char *name,struct security_operations *ops)
其中,register_security/unregister_security用於主安全模組向LSM框架的載入與卸載,mod_reg_security/ mod_unreg_security用於其它安全模組向主安全模組註冊。主安全模組是指除dummy模組之外首先載入進入LSM的安全模組,在主安全模組之後載入的安全模組都屬於從安全模組。從安全模組無法直接向LSM註冊,而需要通過向主安全模組註冊,間接載入進入LSM,並且受主安全模組安全策略的管理。通過這種多安全模組棧式堆疊的機制,LSM提供了對多安全模組支持。但是,堆疊進入LSM的從安全模組並不能獨立的發揮安全作用:從安全模組何時被調用、如何被調用,返回結果的決策,都受主安全模組的管理。如果主安全模組為提供對後繼模組的載入管理的支持,LSM的棧式堆疊機制也就無法再起作用。這種機制實質上是LSM框架在多安全模組管理和決策結果處理方面對主安全模組的依賴。
以SELinux安全模組為例,模組在初始化的過程中,調用LSM的register_security函式,並將LSM的security_ops表指向自身的鉤子函式表。關鍵代碼如下
static _init int selinux_init(void){    ……    if(registcr_security(&selinux_ops);/*調用register_security函式*/    ……}
其中,selinux_ops為Selinux模組實現的hook函式表,其定義為:
extern struct security_operations *security_ops;
register_security函式由LSM提供,其過程為:
int _init register_security(struct_security_operations *ops){    ……    if(security_ops!=&default_security_ops)/*判斷是否有已載入的主安全模組*/        return -EAGAIN;    security_ops=ops; }
模組載入過程中,若檢測到已有主安全模組載入到LSM,則模組只能通過IIlod—reg—security函式向從安全模組註冊。模組卸載時,將LSM的security-ops設定為默認的dummy模組的h00k函式表。mod—reg—security/moo—unreg—security函式由特定的主安全模組提供。由上述代碼可見,安全模組載入的過程,實質上就是將LSM的hook函式表與安全模組實現的hook函式表相關聯的過程。

安全系統調用

LSM在核心中添加了一個通用的安全系統調用,以提供對安全模組安全套用的支持。該調用的接口允許安全模組實施自己的系統調用,對已有的系統調用進行擴展,以保證安全策略的實施。LSM在核心中對安全模組提供的通用接口是sys_security,參數為unsigned int id,unsigned int call,unsigned long *args。一般說來,三個參數分別代表安全模組標識符,系統調用標識符以及調用的參數,但是安全模組可以根據其安全策略和函式的實現,對三個參數進行不同的解釋。安全模組可以根據自身安全策略的需要選擇對安全系統調用進行實現或者不實現,若不需要對此調用進行實現,僅需要令函式syssecurity返回.NOSYS值。

Capabilities機制

Capabilities機制的基本思想是分割超級用戶許可權,防止超級許可權的誤用和濫用,以實現最小特權原則。LSM的設計目標之一是把傳統的分散在核心多處的capabilities機制分離出核心‘,形成一個獨立的capabilities安全模組。Capabilities機制的分離,具有兩方面的優勢:首先,用戶對capabilities機制的使用更加靈活,不需要該機制的用戶只需將其從LSM卸載;其次,capabilities機制的分離,使得對capabilities的後繼研究對Linux核心影響變得很小。
目前,LSM框架已把大部分的capabilities機制獨立出核心,但仍有部分遺留在核心中。例如,標識進程capability使用一個位於taskstruct中的位向量表示,該位向量可以移到taskstruct的安全域中,但由於模組堆疊機制下的安全域共享問題,該位向量及相關邏輯仍保留在核心中。

相關詞條

熱門詞條

聯絡我們