熊聰聰 汪 鵬
(天津科技大學計算機科學與信息工程學院,天津 300222)
USB存儲設備的廣泛應用在給用戶帶來便利的同時也帶來了很大的信息安全隱患,各種針對USB存儲設備的木馬、病毒以及非授權用戶的使用都造成了嚴重的信息安全問題。目前,針對USB存儲設備的安全防護機制大多是在應用層上實現,且主要是對主機端系統的防護。在這種防護方式下,當主機系統受到攻擊和破壞時,信息的安全性不能得到保證;同時由于應用層的權限較低,使得訪問控制機制容易遭到破壞。
對此,本文提出的解決方案是增加一個運行Linux系統的嵌入式平臺(ARM S3C2410)作為安全終端,將訪問控制機制放在此嵌入式平臺中。這種設計方案不僅可以很好地防范針對USB存儲設備的攻擊,而且克服了傳統防護方式的固有缺陷,保障了用戶的信息安全。
嵌入式系統平臺硬件部分采用ARM9系列的S3C2410,它包含 ARM處理器、Flash存儲芯片、SDRAM、LCD、USB主機接口和 USB從設備接口等。USB主機接口與USB從設備接口支持USB1.1協議標準。USB從設備接口負責與主機系統的USB主口進行通信,ARM板上的USB主設備接口負責與外圍USB存儲設備通信。系統硬件結構如圖1所示。

圖1 系統硬件結構圖Fig.1 Structure of system hardware
根據嵌入式Linux平臺的特點和功能實現的需要,設計的系統軟件結構如圖2所示。USB存儲設備訪問控制機制在嵌入式Linux中實現,其中Mass Storage Gadget驅動模塊用來實現訪問控制功能,認證驅動模塊負責接收應用程序發送來的數據并根據預先存儲的賬戶信息進行認證,USB從設備端控制器驅動負責與主機間的底層通信。系統中只有用戶認證應用程序在應用層運行,負責接收用戶輸入的信息。所有的訪問機制和口令都在驅動層中實現,提高了訪問控制機制的安全性。

圖2 系統軟件結構圖Fig.2 Structure of system software
在實現控制器驅動后,可利用Linux Gadget子系統實現對各種USB設備端的應用,如存儲設備、USB轉網口和USB轉串口等。這里通過加載Mass Storage Gadget驅動模塊在S3C2410上實現存儲設備功能,使得ARM板連接到主機時自動識別為USB移動存儲設備。
運行于一個USB外設的系統在Linux內核中被稱為Gadget子系統,分為USB設備控制(USB device control,UDC)層、設備驅動層(Gadget驅動)和 Gadget應用程序接口(Gadget application program interface,Gadget API)層[1]。Linux Gradget系統框架如圖3 所示。

圖3 Linux Gadget系統框架Fig.3 System framework of Linux Gadget
UDC驅動是Gadget子系統中最底層的軟件層,也是硬件相關層。UDC驅動負責控制USB設備和主機間的底層通信,向上層提供與硬件相關操作的回調函數[1]。Gadget API是UDC驅動程序回調函數的簡單包裝,功能為向上提供編程接口。Linux USB設備側驅動程序使用 struct USB_gadget描述 UDC,使用 struct USB_ep表示端點。Gadget API通過這兩個結構對下層硬件進行管理。Gadget驅動層是Linux Gadget子系統中的高層驅動,負責實現struct USB_gadget_driver結構,并調用UDC驅動提供的Gadget API函數usb_gadget_register_driver()和usb_gadget_unregister_driver()在內核中進行注冊和注銷操作[2]。硬件細節隱藏在不同的UDC驅動中,所以Gadget驅動是硬件不相關的,只負責具體設備功能的實現。
Mass Storage Gadget驅動是Gadget子系統中的最高層,使ARM S3C2410連接主機時表現為一個移動存儲設備[3],并使用雙緩沖技術來提高數據吞吐量。
驅動模塊的init()函數使用usb_gadget_register_driver(&fsg_driver)函數完成驅動模塊的注冊,當設備連接時,調用fsg_bind()函數。fsg_bind()函數負責Gadget驅動和下層設備控制器的關聯、分配Mass Storage設備需要的端點以及傳送數據所需的數據緩沖區,其中最主要的功能是創建處理線程函數fsg_main_thread()。線程函數fsg_main_thread()是Gadget設備操作的主要處理函數,負責處理設備的各種操作及事件[4],通過調用 get_next_command()函數不斷讀取主機端的命令,并將之發送給do_scsi_command()函數進行處理[8]。處理線程的生命周期在Gadget設備的fsg_bind()函數回調期間開始,在fsg_unbind()函數調用期間結束。
在Linux Kernel 2.6版本中,USB Gadget子系統的驅動代碼在/kernel/drivers/usb/gadget目錄下。配置好內核中所需的USB Gadget功能,執行make modules SUBDIRS=/drivers/usb/gadget命令,則在Gadget目錄下生成g_file_storage.ko文件,此時驅動模塊已經可以使用。在加載驅動之前,必須根據硬件設計在內核中添加設備插入通知函數。此外,由于USB主機和設備接口均需要48 MHz的時鐘,而ARM S3C2410中使用USB鎖相環(USB phase locked loop,UPLL)為 USB產生時鐘,所以還需向UPLLCON(UPLL控制寄存器)中寫入相應值,以提供USB所需的時鐘。
修改 arch/arm/mach-s3c2410/mach-smdk2410.c添加內核通知函數的主要代碼如下。


設備上電啟動后加載驅動,在終端輸入insmod g_file_storage_ko file=/dev/sda removable=1命令即可掛載驅動模塊,其中參數file=/dev/sda表示將插入的USB存儲設備在/dev目錄下生成的設備文件用于數據交互,removable參數表示是否為可移除設備。加載完畢后,將S3C2410設備的USB Device接口與主機系統的USB主機接口使用USB線連接,主機將其識別為USB存儲設備。
訪問控制是為了限制訪問用戶對于關鍵資源(處理器、路由器、應用程序、數據文檔和系統文檔)的訪問,防止用戶的非授權操作所造成的信息安全問題[5]。用戶只有在經過身份認證并得到授權后,才能根據訪問控制機制預先設定的規則對資源進行訪問。
本方案采用基于角色的訪問控制機制,通過定義不同角色權限并為訪問用戶分配角色實現訪問控制,具有實現簡單、責任獨立和節約管理開銷等優點[6]。在系統中,認證驅動模塊負責用戶角色的分配并輸出認證結果,Mass Storage Gadget驅動模塊則根據認證結果分配權限實現訪問控制。
本方案采用基于角色的訪問控制方式,將用戶角色分為角色A(讀權限)、角色B(寫權限)、角色C(讀寫權限)和角色D(無權限)。用戶通過應用程序與認證驅動模塊交互,獲取角色并得到相應的訪問權限。在Mass Storage Gadget驅動中,do_scsi_command()函數負責對命令進行解析并做出相應處理,修改此函數中對于讀寫命令的處理可實現預先的規則設定。如角色A讀權限設定可通過修改SC_READ_10命令的處理實現,主要代碼如下。


認證模塊負責接收用戶登錄信息并分配相應角色。由于Linux系統中用戶一般只能在用戶態執行,因此不具有訪問內核層中的數據結構和程序的權限;而對于存儲設備的訪問控制又在驅動模塊中也就是內核層實現,所以必需解決用戶態和內核態的轉換問題,才能進行相應的權限控制。在Linux中,可通過系統調用處理程序、調度程序和中斷處理程序三種方式實現用戶態和內核態的轉換[7]。以下采用驅動模塊引用機制也就是系統調用處理程序的方式設計和實現認證模塊。
3.2.1 Linux 驅動模塊引用機制
在Linux模塊機制中,用戶可以把新的功能作為一個模塊動態地加入內核。一般使用insmod命令裝載模塊,然后使用內核的符號表解析模塊中未解析的符號。modprobe命令與insmod命令類似,它也可以將模塊裝載到內核,另外會在當前模塊搜索路徑中查找依賴模塊,并按一定的順序裝載到內核中。Linux內核中的公共內核符號表保存了所有的全局內核項,包括模塊訪問的符號和相應地址。驅動模塊被裝入內核時可以利用EXPORT_SYMBOL和EXPORT_SYMBOL_GPL宏導出符號到公共內核符號表中,同時可以被其他模塊引用,引用模塊依賴于導出符號模塊[8]。
3.2.2 認證模塊的實現
根據Linux的驅動模塊引用機制,通過添加認證驅動模塊實現認證過程。系統認證流程如圖4所示。

圖4 系統認證流程圖Fig.4 Flowchart of system certification
設計方法是將認證驅動模塊實現為字符驅動,提供open、write、read操作并導出表示角色的符號(User)。同時設定Mass Storage Gadget驅動模塊引用認證模塊導出的符號,并使用modprobe命令加載各驅動模塊。認證時首先由認證驅動模塊從應用程序中接收信息,并根據Flash中預先存放的口令信息對用戶身份進行認證;然后認證驅動模塊根據認證結果導出符號并向應用程序返回狀態信息;最后由Mass Storage Gadget驅動模塊根據不同的符號值賦予用戶相應的訪問權限。
認證應用程序的作用是接收用戶信息并與認證模塊交互。系統中應用程序使用QT4編寫,采用多線程編程方式。主線程負責接收用戶輸入的口令信息并將其傳遞給認證模塊,然后阻塞等待認證模塊的反饋,子線程負責加載設備。通過用戶認證應用程序,用戶可以方便地選擇加載USB存儲設備并輸入口令,在獲取反饋信息后進行相應權限的訪問。
用戶打開認證應用程序,輸入口令進行認證,獲取角色權限對設備進行訪問,如發生越權訪問,則發出警告信息。經過測試證明,系統可以有效地對USB存儲設備進行訪問控制,用戶只能在認證授權后按照相應權限進行訪問。
本文提出了一種利用嵌入式平臺實現USB存儲設備訪問控制的方案,以運行Linux的ARM S3C2410為例給出了詳細的設計和實現方法。該方案將訪問控制機制放在嵌入式平臺中,實現主機系統與外圍USB存儲設備物理上的隔離;同時,所有對USB存儲設備的訪問均由嵌入式平臺進行安全控制。試驗證明,此方案克服了傳統防護方式過于依賴主機系統的缺陷,很好地解決了使用USB存儲設備所引起的信息安全隱患,所涉及的軟件模塊和訪問控制機制的設計可以方便地應用于其他的嵌入式Linux平臺,具有很好的移植性和參考價值。
[1]Linux-USB Community.Linux-USB Gadget API framework[EB/OL].[2005 -06 -08].http://www.linux - usb.org/gadget/.
[2]李傳偉,胡金春.嵌入式Linux下USB Gadget驅動框架研究[J].航天控制,2006,24(6):51 -55.
[3]Xu Zhe,Liu Zhuo,Zhang Hua,et al.Development of Linux based USB device driver for portable spectrometer[C]//Proceedings of the 21st Annual International Conference on Chinese Control and Decision Conference,2009:5125 -5128.
[4]劉超.Linux平臺下USB大容量存儲設備驅動程序的改進與優化[D].北京:北京交通大學,2008.
[5]段云所,魏仕民,唐禮勇,等.信息安全概論[M].北京:高等教育出版社,2003:114-126.
[6]韓若飛,汪厚祥.基于任務-角色的訪問控制模型研究[J].計算機工程與設計,2007,28(4):800 -802.
[7]Bovet D P,Cesati M.深入理解 LINUX 內核[M].3版.陳莉君,馮銳,牛欣源,譯.北京:中國電力出版社,2007.
[8]Corbet J,Rubinia A,Kroah-Hartman G.Linux設備驅動程序[M].2版.魏永明,耿岳,鐘書毅,譯.北京:中國電力出版社,2006.