LSMとは
LSM(Linux Security Module)とは,kernel2.6から実装されたセキュリティフレームワーク.SELinuxやTOMOYO Linuxでも使われていて,チェックが必要な箇所でフックがおこり,登録されたコールバック関数が呼び出される.
インターフェースの外から
サンプルを書いてたんですけど,上手くいかなかったので,コピペはやめたほうがいいです.
/* bobulsm.c */
static int bobulsm_inode_mkdir(struct inode *inode, struct dentry *dentry,
umode_t mask)
{
printk("bobulsm: inode_mkdir called.\n");
/* Return 0 if permission is granted. */
return -EPERM;
}
static struct security_operations bobulsm_ops = {
.name = "bobulsm",
.inode_mkdir = bobulsm_inode_mkdir,
};
static int __init bobulsm_init(void){
if (register_security(&bobulsm_ops))
panic("bobulsm: Occurred an error at register_security(&bobuhiro11lsm_ops).\n");
else
printk("bobulsm: registered surely.\n");
return 0;
}
security_initcall(bobulsm_init);
MODULE_DESCRIPTION("BOBULSM");
security_operations構造体に,イベントが発生した時にやらせたい関数を登録します.ここでは,ディレクトリの作成時に,呼び出されるように,inode_mkdirメンバにbobulsm_inode_mkdirを登録しました.これで,ディレクトリ作成時に,bobulsm_inode_mkdirが呼ばれるはずです.
cd linux-3.8.8/security
wget http://bobuhiro11.net/wordpress/wp-content/uploads/2013/06/bobulsm.tar
tar xvf bobulsm.tar
rm bobulsm.tar
そのあとは,『Linux Security Modulesを作りたい』こちらに詳しく書いてあるので,参考にしました.これで上手くいくはずだったんですけど,どうも動いてくれない(泣).
dmesgには,このように出力されてます.なにか手掛かりを教えてくれると喜びます.
[ 0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-3.8.8 root=UUID=b5af552c-3516-48dc-8175-b7ce91be3e60 ro security=bobulsm crashkernel=384M-2G:64M,2G-:128M quiet splash vt.handoff=7
インターフェースの内から
kernelの中身です.
/*
*
* include/linux/security.h
* security_operations構造体は,イベント発生時に呼び出すコールバック関数を
* 登録するための構造体です.
* LSMを使うときは,この構造体のインスタンスを作って,いろいろ登録してやると
* 良さそうです.
*
*/
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);
...
void (*audit_rule_free) (void *lsmrule);
#endif /* CONFIG_AUDIT */
};
/*
*
* security/security.h
* デフォルトのopsです.
*
*/
static struct security_operations *security_ops;
static struct security_operations default_security_ops = {
.name = "default",
};
/*
*
* include/linux/init.h
* LSM自身の初期化の関数群の始まりと終わりを示す.
*/
typedef int (*initcall_t)(void);
extern initcall_t __security_initcall_start[], __security_initcall_end[];
/*
*
* security/security.c
* LSMの実際の初期化関数です.
*
* 『security_init() -> security_fixup_ops() -> set_to_cap_if_null()』
* opsの中にまだ登録されていないコールバックがあれば,
* デフォルトで上書きする.
*
* 『security_init() -> do_security_initcalls()』
* __security_initcall_startと__security_initcall_endで
* 囲まれた初期化関数群を実行する.
*
*/
int __init security_init(void)
{
printk(KERN_INFO "Security Framework initialized\n");
security_fixup_ops(&default_security_ops);
security_ops = &default_security_ops;
do_security_initcalls();
return 0;
}
/*
*
* security/security.c
*
*/
#define set_to_cap_if_null(ops, function) \
do { \
if (!ops->function) { \
ops->function = cap_##function; \
pr_debug("Had to override the " #function \
" security operation with the default.\n"); \
} \
} while (0)
void __init security_fixup_ops(struct security_operations *ops)
{
set_to_cap_if_null(ops, ptrace_access_check);
set_to_cap_if_null(ops, ptrace_traceme);
set_to_cap_if_null(ops, capget);
set_to_cap_if_null(ops, capset);
...
}
static void __init do_security_initcalls(void)
{
initcall_t *call;
call = __security_initcall_start;
while (call < __security_initcall_end) {
(*call) ();
call++;
}
}
/*
*
* security/security.c
* 外部から引数で与えられたopsをverify()でチェックして登録する.
*
*/
int __init register_security(struct security_operations *ops)
{
if (verify(ops)) {
printk(KERN_DEBUG "%s could not verify "
"security_operations structure.\n", __func__);
return -EINVAL;
}
if (security_ops != &default_security_ops)
return -EAGAIN;
security_ops = ops;
return 0;
}
/*
*
* security/security.c
* 引数で与えられたopsで正しいかチェックする.
* security_fixup_ops()を使って,opsの中で未定義のコールバックがあれば,
* デフォルトでうめる.
*
*/
static inline int __init verify(struct security_operations *ops)
{
/* verify the security_operations structure exists */
if (!ops)
return -EINVAL;
security_fixup_ops(ops);
return 0;
}
動かないサンプルで申し訳ありません.
参考
Linux Security Modulesを作りたい
Introduction to Linux Security Modules (LSM)
Android雑記