バイナリラッパ以外のラッパ
某MLにて話題にしたので、まとめ。
LIDSなどでBusyBoxを使う際に、シンボリックリンクやハードリンクでは、アプレットごとにアクセス制御を設定することができません。BusyBoxの概要やバイナリラッパでの解決法など、詳しくは次を参照してください。
BusyBoxでは、/bin/busyboxにリンクを張って使うことが多いですが、Usageにもあるように
busybox [function] [arguments]...
という使いかたもできます。たとえば、
busybox ls
とやれば、lsとして動くわけです。
で、あるときなんとなくexecveのmanページを見ていたら、
書式 #includeint execve(const char *filename, char *const argv, char *const envp); 説明 execve() は、filename によって指定されたプログラムを実 行する。 filename は、バイナリ実行形式か 、"#! inter- preter [arg]" という形式の行で始まるスクリプトでなけれ ばならない。後者の場合、interpreter は適切な実行ファイ ルのパス名でなければならず、それ自身がスクリプトであっ てはならない。そしてそれは interpreter [arg] filename の形で呼び出される。
と書かれていました。それだったら
#!/bin/busybox
と一行書いたファイルを実行形式にして、例えば/bin/lsとしてセーブしておけば、lsを実行したときに
/bin/busybox ls
と動作してくれるのではないかなぁ、などと思って、/bin/busyboxと"#!/bin/busybox"と書いた/bin/lsを配置し実行してみましたが、
# ls busybox: applet not found #
そんなに単純ではありません。
これは、filenameにはスクリプトのフルパス名が入るため、
/bin/busybox /bin/ls
と実行されてしまうためです。ということで、BusyBoxの方で、フルパス名に対応できるよう修正し、実行してみます。
# cat /bin/ls #!/bin/busybox # ls -l /bin/l* -rwxr-xr-x 1 root root 18128 Jan 11 00:06 /bin/link -rwxr-xr-x 1 root root 29840 Jan 11 00:06 /bin/ln -rwxr-xr-x 1 root root 79412 Sep 29 20:27 /bin/loadkeys -rwxr-xr-x 1 root root 25756 Feb 9 21:43 /bin/login -rwxr-xr-x 1 root root 15 Feb 21 04:47 /bin/ls -rwxr-xr-x 1 root root 93560 Jan 11 00:06 /bin/ls.orig #
バイナリラッパでは、アーキテクチャごとにアセンブラコードを書く必要がありましたが、このいわゆる「スクリプトラッパ」では、その必要がなく、また15バイトで済みます。
ただし、問題として例えば
# cat
と実行したときに、psコマンドでプロセスを見ると
/bin/busybox /bin/cat
と表示され、見にくいです。
あとLIDSではACL_DISCOVERYモードでアクセス違反のログを取得しようとした場合、全てbusyboxの違反となってしまうので、ポリシーを構築するのに、ログを参考にすることができなくなってしまいます。
(ということで、LIDSではこのスクリプトラッパは使いませんでした。LIDSのログ出力方法に手を加える必要があるでしょう)
別の案
ちなみに、#!/bin/busyboxじゃなくても、例えばcatの場合、
としたら、BusyBoxにパッチを当てる必要ないよねぇ、という案もありましたが、
/bin/shはどうするの?
ということになりました。/bin/shもBusyBox使いたいですし。
#!/bin/busyboxの方は、スクリプトをコピーするだけでインストールも簡単だし、呼出コストも少なそうだし。
スクリプトラッパ対応パッチ
パッチは以下の通り。BusyBoxのバージョン1.4.1用です。
diff -Naru busybox-1.4.1/applets/busybox.c busybox-1.4.1.script/applets/busybox.c --- busybox-1.4.1/applets/busybox.c 2007-01-25 06:34:50.000000000 +0900 +++ busybox-1.4.1.script/applets/busybox.c 2007-02-20 10:09:58.000000000 +0900 @@ -104,7 +104,7 @@ if (argc == 1 || !strcmp(argv[1], "--help") ) { if (argc > 2) { - applet_name = argv[2]; + applet_name = bb_get_last_path_component(argv[2]); run_applet_by_name(applet_name, 2, argv); } else { const struct BB_applet *a; @@ -140,7 +140,7 @@ puts("\n"); return 0; } - } else run_applet_by_name(argv[1], argc - 1, argv + 1); + } else run_applet_by_name(bb_get_last_path_component(argv[1]), argc - 1, argv + 1); bb_error_msg_and_die("applet not found"); }
インストーラ込みのパッチは、気分が向いたらそのうち作りますね〜。