monolithic kernel

Linux Security Modulesを作りたい

June 24, 2011

    Linuxのセキュリティ周りを拡張するフレームワークであるLinux Security Modules(LSM)を作ってみます。LSMはSELinuxやTOMOYO Linuxの実装に使われており、LSMを利用することでシステムのさまざまな部分をフックしてアクセス制御などの処理を実現することができるようになります。

    とりあえず以下の記事にあったLSMのスケルトンを実際にUbuntuに組み込んでみたのでメモしておきます。

    Writing a Skeleton Linux Security Module | recluze

    インストール

    カーネル構築の準備

    必要なツールとカーネルのソースコードをインストールしておきます。

    cd /usr/src
    sudo apt-get install -y build-essential libncurses-dev ncurses-dev kernel-package linux-source-2.6.38
    sudo tar vxf linux-source.2.6.38.tar.bz2

    うちの環境(Ubuntu 11.04)ではこのままだとエラーになってしまったため、こちらを参考に対処。

    sudo vi /usr/src/linux-source-2.6.38/ubuntu/omnibook/Makefile

    以下のように修正。

    ...
    
    # 追加
    PWD = $(shell pwd)
    ifeq ($(KERNELRELEASE),)
    
    ...
    
    # 削除
    # PWD = $(shell pwd)
    
    ...

    LSMの追加

    LSMのスケルトンをダウンロードしてきてカーネルに組み込みます。

    wget http://csrdu.org/pub/nauman/files/blabbermouth.tar.gz
    tar vxf blabbermouth.tar.gz
    sudo mv lsm-tut-files/blabbermouth /usr/src/linux-source-2.6.38/security
    cd /usr/src/linux-source-2.6.38/security
    sudo vi blabbermouth/blabbermouth.c

    そのままだと大量のログを吐いて操作不能になるのとか、記述が古かったりするのを修正。

    ...
    
    static int blabbermouth_file_permission(struct file *file, int mask)
    {
      /* printk("blabbermouth: file_permission called\n"); */
      return 0;
    }
    
    ...
    
    static int __init blabbermouth_init(void) {
      ...
    }
    
    security_initcall(blabbermouth_init);

    MakefileとKconfigに追加したLSMを含める設定を追記します。

    cd /usr/src/linux-source-2.6.38/security
    sudo vi Makefile
    sudo vi Kconfig

    Makefile

    ...
    
    obj-$(CONFIG_KEYS)      += keys/
    subdir-$(CONFIG_SECURITY_SELINUX) += selinux
    subdir-$(CONFIG_SECURITY_SMACK)   += smack
    subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
    subdir-$(CONFIG_SECURITY_APPARMOR)  += apparmor
    subdir-$(CONFIG_SECURITY_YAMA)    += yama
    # 追加
    subdir-$(CONFIG_SECURITY_BLABBERMOUTH) += blabbermouth
    
    ...
    
    obj-$(CONFIG_SECURITY_SELINUX)    += selinux/built-in.o
    obj-$(CONFIG_SECURITY_SMACK)    += smack/built-in.o
    obj-$(CONFIG_AUDIT)     += lsm_audit.o
    obj-$(CONFIG_SECURITY_TOMOYO)   += tomoyo/built-in.o
    obj-$(CONFIG_SECURITY_APPARMOR)   += apparmor/built-in.o
    obj-$(CONFIG_SECURITY_YAMA)   += yama/built-in.o
    # 追加
    obj-$(CONFIG_SECURITY_BLABBERMOUTH) += blabbermouth/built-in.o

    Kconfig

    ...
    
    source security/selinux/Kconfig
    source security/smack/Kconfig
    source security/tomoyo/Kconfig
    source security/apparmor/Kconfig
    source security/yama/Kconfig
    source security/blabbermouth/Kconfig
    
    ...

    カーネルの構築

    現在利用しているカーネルの設定をもとにLSMを組み込んだカーネルを構築します。make oldconfigを実行すると追加したLSMを有効にするかどうか聞かれるので、yを選択して有効にしてください。

    cd /usr/src/linux-source-2.6.38
    sudo cp /boot/config-2.6.38-8-generic .config
    sudo make oldconfig
    sudo make-kpkg --initrd --revision=20110625 kernel_image
    cd ..
    sudo dpkg -i linux-image-2.6.38.2_20110625_amd64.deb

    LSMを利用する設定

    GRUBの設定を変更して作成したLSMが利用されるようにします。

    sudo vi /etc/default/grub
    sudo update-grub

    以下のように記述。

    GRUB_CMDLINE_LINUX="security=blabbermouth"

    動作確認

    再起動するとLSMが組み込まれたカーネルで起動します。printk関数で出力したログは/var/log/dmesgに保存されるので、blabbermouth:で始まるログがあることを確認してください。

    less /var/log/dmesg

    困っているところ

    とりあえずLSMを組み込んだカーネルを起動させることには成功したのですが、分からない点がいろいろと。

    初期化時のログが出力されない

    LSMの初期化を行うblabbermouthinit内でprintk関数を呼び出してもログが残ってくれません。ログレベルをKERNEMERGなどとすると画面上には表示されるので、実行されてはいるみたいですし、他のLSMの出力するログは出力されてるみたいなのですが……。

    securitymoduleenableを呼んでいない

    ドキュメントや他のLSMのソースを眺めていると、どうも初期化時にsecuritymoduleenable関数を呼び出さなければならないようなのですが、今回参考にしたサンプルではそれが行われていませんでした。試しにsecuritymoduleenable関数を呼び出すように書き換えてみたのですが、動作しなくなってしまいました。securitymoduleenable関数のコードを見た感じだと、動作しないほうが正しいような気すらしてしまうのですが、どうなっているんでしょうかね。

    makeが遅い

    LSMを1行いじっただけで30分近く待たされてしまうのはちょっと耐えられません。何かがおかしい気がします。

    おわりに

    AKARIを使えばカーネルの再構築をすることなくLSMを実装することができると聞いたので、試してみたいなぁと思っています。