學習LSM(Linux security module)之二:編寫並運行一個簡單的demo


  各種折騰,經過了一個蛋疼的周末,終於在Ubuntu14.04上運行了一個基於LSM的簡單demo程序。

一:程序編寫

  先簡單的看一下這個demo:

//demo_lsm.c
#include <linux/lsm_hooks.h> #include <linux/sysctl.h> static unsigned long long count = 0; int demo_task_create(unsigned long clone_flags) { printk("[+geek] call task_create(). count=%llu\n", ++count); return 0; } static struct security_hook_list demo_hooks[] = { LSM_HOOK_INIT(task_create,demo_task_create), }; void __init demo_add_hooks(void) { pr_info("Demo: becoming mindful.\n"); //打印相關信息,可以通過dmesg | grep Yama:查看 security_add_hooks(demo_hooks, ARRAY_SIZE(demo_hooks)); //添加安全模塊函數 } static __init int demo_init(void){ demo_add_hooks(); return 0; } security_initcall(demo_init);

   根據(一)的yama可以得出,編寫一個基於LSM的安全模塊的基本流程:

    1>確定需要hook的函數

    2>對hook函數進行填充,添加自己的邏輯(安全檢查)

    3>添加到在security_hook_list的數據結構里

    4>對這個有注冊邏輯的函數進行注冊

  1:確定需要hook的函數:

    1>用戶創建進程需要調用系統調用 sys_fork()/sys_vfork()/sys_clone()

    2>sys_fork()等函數中調用 do_fork()

    3>do_fork()調用copy_process()

    4>copy_process()調用security_task_create()這里便是hook點了,可以進行自己的邏輯

    5>security_task_create()的主體就是security_hook_list的task_create()

  2:對hook函數進行必要的填充,添加自己的邏輯(額外的安全檢查)

    在這里,只是為了簡單的檢測自己的代碼是否能夠正常運行,所以,只用了簡單的printk,詳情請看demo_task_create函數。

  3:添加到在security_hook_list的數據結構里

    額外說一點:關於這一步,在4.0之前后某個版本,打了個補丁,所以實現方式會有不同,先看一下4.0以前:

struct security_operations {
         char name[SECURITY_NAME_MAX + 1]; 
         int (*ptrace_access_check) (struct task_struct *child, unsigned int mode);
         int (*ptrace_traceme) (struct task_struct *parent);
         int (*capget) (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
         int (*capset) (struct cred *new, const struct cred *old, const kernel_cap_t *effective, const kernel_cap_t *inheritable, const kernel_cap_t *permitted);
         int (*capable) (const struct cred *cred, struct user_namespace *ns, int cap, int audit);
         int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
      ....

       這種實現方式有個缺點,無論hook幾個函數,都會替每個指針占一個位置,由於內核空間,內存十分寶貴,這種占空間西行為產生了很大的浪費。所以實現換了一種方式,如下:

struct security_hook_list {
         struct list_head                list;
         struct list_head                *head;
         union security_list_options     hook;
 };

     然后,security_list_options以一種聯結體的方式存在,然后通過侵入式鏈表連接,可以有效的節省空間。

     言歸正傳。數據結構可以通過LSM_HOOK_INIT宏來進行填充,詳情可以看(一):

  4:對這個有注冊邏輯的函數進行注冊

    在這一點上,簡單的security_initcall(demo_init);就可以了

二:Makefile和Kconfig編寫

    在編寫這兩個文件時,由於在2.6.X后,lsm的模塊不允許通過insmod動態加載到內核中,需要在編譯內核時添加,所以,需要謹慎,否則容易出錯(-_-)。

  如下:

//Kconfig
config SECURITY_DEMO
bool "demo support" depends on SECURITY default n help introduction of demo modules

 

  

//Makefile
obj-$(CONFIG_SECURITY_GEEK) := demo.o demo-y := demo_lsm.o

 

     將這兩個文件以及前文的 demo_lsm.c 放到./linux-X.X.X(X.X.X>4.0.0)/security/demo(自己創建)中,然后修改security下的Kconfig和Makefile,這里可以參照SElinux或者yama的格式進行編寫,      但需要注意的是,在Linux>4.2之后,Yama默認只能依附在其它模塊上,所以,最好對照SELinux。

#
# Makefile for the kernel security code
#

obj-$(CONFIG_KEYS)            += keys/
subdir-$(CONFIG_SECURITY_SELINUX)    += selinux
subdir-$(CONFIG_SECURITY_DEMO)        += demo
subdir-$(CONFIG_SECURITY_SMACK)        += smack
subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
subdir-$(CONFIG_SECURITY_APPARMOR)    += apparmor
subdir-$(CONFIG_SECURITY_YAMA)        += yama


# always enable default capabilities
obj-y                    += commoncap.o
obj-$(CONFIG_MMU)            += min_addr.o

# Object file lists
obj-$(CONFIG_SECURITY)            += security.o
obj-$(CONFIG_SECURITYFS)        += inode.o
obj-$(CONFIG_SECURITY_SELINUX)        += selinux/
obj-$(CONFIG_SECURITY_DEMO)        += demo/
obj-$(CONFIG_SECURITY_SMACK)        += smack/
obj-$(CONFIG_AUDIT)            += lsm_audit.o
obj-$(CONFIG_SECURITY_TOMOYO)        += tomoyo/
obj-$(CONFIG_SECURITY_APPARMOR)        += apparmor/
obj-$(CONFIG_SECURITY_YAMA)        += yama/
obj-$(CONFIG_CGROUP_DEVICE)        += device_cgroup.o

# Object integrity file lists
subdir-$(CONFIG_INTEGRITY)        += integrity
obj-$(CONFIG_INTEGRITY)            += integrity/

 

 

#
# Security configuration
#

menu "Security options"

source security/keys/Kconfig

.....

source security/selinux/Kconfig
source security/demo/Kconfig
source security/smack/Kconfig
source security/tomoyo/Kconfig
source security/apparmor/Kconfig
source security/yama/Kconfig

source security/integrity/Kconfig

choice
    prompt "Default security module"
    default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX
    default DEFAULT_SECURITY_DEMO if SECURITY_DEMO
    default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
    default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
    default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
    default DEFAULT_SECURITY_DAC

    help
      Select the security module that will be used by default if the
      kernel parameter security= is not specified.

    config DEFAULT_SECURITY_SELINUX
        bool "SELinux" if SECURITY_SELINUX=y
    
 config DEFAULT_SECURITY_DEMO bool "demo" if SECURITY_DEMO=y

    config DEFAULT_SECURITY_SMACK
        bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y

    config DEFAULT_SECURITY_TOMOYO
        bool "TOMOYO" if SECURITY_TOMOYO=y

    config DEFAULT_SECURITY_APPARMOR
        bool "AppArmor" if SECURITY_APPARMOR=y

    config DEFAULT_SECURITY_DAC
        bool "Unix Discretionary Access Controls"

endchoice

config DEFAULT_SECURITY
    string
    default "selinux" if DEFAULT_SECURITY_SELINUX
    default "demo" if DEFAULT_SECURITY_DEMO
    default "smack" if DEFAULT_SECURITY_SMACK
    default "tomoyo" if DEFAULT_SECURITY_TOMOYO
    default "apparmor" if DEFAULT_SECURITY_APPARMOR
    default "" if DEFAULT_SECURITY_DAC

endmenu

 

 三:編譯安裝運行內核

    1>將linux內核源碼和二里面添加和更改的部分移到 /usr/src中。

    2> cp /boot/config-‘uname -r’ /usr/src/kernels/linux3.2.14/.config,將原系統內核配置拷貝到需要編譯的源碼上

    3> make menuconfig,這里可能會失敗,這時候,你需要去apt-get install libncurses5-dev:截圖如下:

                

      

      

      在配置上,需要自己根據自己的水平來進行配置,否則極易弄巧成拙(-_-)

    4>make bzImage -jN(N為具體數字,代表線程數),可以根據虛擬機內核數 X2來確定N的具體值,以節約時間

    5>make modules -jN,同上

    6>make modules_install

    7>make install

    8>部分可能需要修改grub的default為0,經測ubuntu14.04自動修改了,不需要自己去改

    9>reboot ,並且demesg,可以得到如下:

      

      demo就運行成功了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM