monolithic kernel

Linux Security Modulesを作りたい

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

security_module_enableを呼んでいない

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

makeが遅い

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

おわりに

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