Microsoft PowerPoint - BusyBox\203X\203N\203\212\203v\203g\203

SELinuxユーザ会2007年夏の勉強会
~小ネタ~
BusyBoxのWrapperについて
日本SELinuxユーザ会
(セキュアOSユーザ会)
宍道 洋
BusyBoxとは?
沢山の
沢山のコマンド(
コマンド(アプレット)
アプレット)を一
つのバイナリ
つのバイナリにまとめ
バイナリにまとめ、
にまとめ、コンパク
トにしたもの
スイス・
スイス・アーミー・
アーミー・ナイフのよう
ナイフのよう
なツール
通常リンク
通常リンクを
リンクを張って使用
って使用する
使用する
~ # busybox
BusyBox v1.2.2 (2006.10.31(2006.10.31-00:55+0000) multimulti-call binary
Usage: busybox [function] [arguments]...
or: [function] [arguments]...
BusyBox is a multimulti-call binary that combines many common Unix
utilities into a single executable. Most people will create
create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as!
共通コード
共通コードをまとめて
コードをまとめて、
をまとめて、フットプ
リントを
リントを小さくできる
Currently defined functions:
[, [[, addgroup,
addgroup, adduser,
adduser, ash, basename,
basename, busybox,
busybox, cat, chgrp,
chgrp,
chmod,
chmod, chown,
chown, chroot,
chroot, clear, cmp,
cmp, cp, cut, date, dc, dd,
dd, delgroup,
delgroup,
deluser,
deluser, df,
df, dirname,
dirname, dmesg,
dmesg, du, dumpleases,
dumpleases, e2fsck, echo, egrep,
egrep,
env,
env, expr,
expr, false, fdisk,
fdisk, fgrep,
fgrep, find, free, fsck,
fsck, fsck.ext2, fsck.ext3,
getopt,
getopt, getty,
getty, grep,
grep, gunzip,
gunzip, gzip,
gzip, halt, head, hexdump,
hexdump, hostid,
hostid,
hostname, httpd,
httpd, hwclock,
hwclock, id, ifconfig,
ifconfig, ifdown,
ifdown, ifup,
ifup, inetd,
inetd, init,
insmod,
insmod, kill, killall,
killall, klogd,
klogd, less, ln,
ln, logger, login, logname,
logname,
ls,
ls, lsmod,
lsmod, md5sum, mkdir,
mkdir, mke2fs, mkfs.ext2, mkfs.ext3, mknod,
mknod,
mkswap,
mkswap, modprobe,
modprobe, more, mount, mv,
mv, netstat,
netstat, nslookup,
nslookup, passwd,
passwd,
pidof,
pidof, ping, pivot_root,
pivot_root, poweroff,
poweroff, ps,
ps, pwd,
pwd, rdate,
rdate, reboot, reset,
rm,
rm, rmdir,
rmdir, rmmod,
rmmod, route, runrun-parts, sed,
sed, sh,
sh, sha1sum, sleep, sort,
strings, stty,
stty, su,
su, swapoff,
swapoff, swapon,
swapon, sync, syslogd,
syslogd, tail, tee,
telnet, telnetd,
telnetd, test, time, top, touch, true, tty,
tty, udhcpc,
udhcpc, udhcpd,
udhcpd,
umount,
umount, uname,
uname, uniq,
uniq, uptime, usleep,
usleep, vi, wc,
wc, wget,
wget, which, whoami,
whoami,
xargs,
xargs, yes, zcat
→ 組込み
組込み向け
~#
Ex.)
ln –s /bin/busybox /bin/ps
ln –s /bin/busybox /bin/vi
もしくは引数
もしくは引数で
引数で直接指定
Ex.)
/bin/busybox ls -l
/bin/busybox date
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
2
BusyBoxとセキュアOS
BusyBoxをリンクで呼び出すと、リンク元の実体
に定義されたアクセス制御しか働かない。
SELinux、LIDS → 実体のinode内の情報を利用
AppArmor → リンク解決後のパス名を利用
リンクではなく実ファイルからの呼び出し(Wrapperの利用)
ls ls
inode
busybox
cp cp
inode
inode
ping
ping
inode
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
3
バイナリラッパ
/bin/busyboxを呼び出すバイナリを作成する
Cで書くとこんな感じ
void main(int argc, char* argv[], char* envp[]) {
argv[0] = ”cat”;
execve(”/bin/busybox”, argv, envp);
}
これをアセンブラで記述(サイズは1k未満)
/bin # ls -l
-rwxr-xr-x
-rwxr-xr-x
-rwxr-xr-x
-rwxr-xr-x
-rwxr-xr-x
...
1
1
1
1
1
root
root
root
root
root
root
root
root
root
root
696
692
688
688
692
Aug
Aug
Aug
Aug
Aug
17
17
17
17
17
12:01
12:01
12:01
12:01
12:01
addgroup
adduser
ash
cat
chgrp
→ アーキテクチャ毎にコードを作成・メンテナンスする必要
参考:「BusyBoxを使った組み込み機器でLIDSを動かすには」(佐藤 祐介氏)
http://www.selinux.gr.jp/LIDS-JP/document/general/web_lids_busybox/main.html
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
4
じゃ、シェルスクリプトでやってみる?
例えば“cat”
#!/bin/sh
/bin/busybox cat $*
じゃあ、“sh”は?
#!/bin/sh
/bin/busybox sh $*
これもbusyboxだったりする・・・
例えば“cp”が
#!/bin/sh
/bin/busybox rm $*
と置き換えられたら・・・
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
5
execve()を見てみた
execve(2)のmanpage
書式
#include <unistd.h>
int execve(const char *filename, char *const argv[],
char *const envp[]);
説明
execve() は、filename によって指定されたプログラムを実行する。Filename
は、バイナリ実行形式か、“
“#! interpreter
interpreter [arg
[arg]
arg]”という形式
という形式の
形式の行で始まる
スクリプトでなければならない
スクリプトでなければならない。
でなければならない。後者の場合、interpreter は適切な実行ファ
イルのパス名でなければならず、それ自身がスクリプトであってはならない。
そしてそれは interpreter [arg
[arg]
arg] filename の形で呼び出される。
される。
では、“#!/bin/busybox”と書いたファイルだけでOK?
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
6
スクリプトラッパ
/bin/lsに“#!/bin/busybox”と書いたファイ
ルを置いて実行
# ls
busybox: applet not found
#
lsのフルパスがbusyboxの引数として入るため
“/bin/ls” ≠ “ls”
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
7
BusyBoxの修正
アプレット名を拾う部分を修正
+
+
applet_name = argv[0];
run_applet_and_exit(argv[0], argv);
argv);
applet_name = bb_get_last_path_component(argv[0]);
run_applet_and_exit(applet_name,
run_applet_and_exit(applet_name, argv);
argv);
フルパスからファイル名のみ引っ張ってくる
# cat /bin/ls
/bin/ls
#!/bin/busybox
#!/bin/busybox
# ls -l /bin/l*
-rwxr1
rwxr-xrxr-x
-rwxr1
rwxr-xrxr-x
-rwxr1
rwxr-xrxr-x
-rwxr1
rwxr-xrxr-x
-rwxr1
rwxr-xrxr-x
-rwxr1
rwxr-xrxr-x
#
2007年7月4日
root
root
root
root
root
root
root
root
root
root
root
root
18128
29840
79412
25756
15
93560
Jan
Jan
Sep
Feb
Feb
Jan
11
11
29
9
21
11
00:06
00:06
20:27
21:43
04:47
00:06
SELinuxユーザ会2007年夏の勉強会
/bin/link
/bin/ln
/bin/ln
/bin/loadkeys
/bin/loadkeys
/bin/login
/bin/ls
/bin/ls
/bin/ls.orig
/bin/ls.orig
8
execve()の制限
説明
execve() は、filename によって指定されたプログラムを実行する。Filename
は、バイナリ実行形式か、“#! interpreter [arg]”という形式の行で始まる
スクリプトでなければならない。後者
後者の
場合、interpreter は適切な
適切な実行ファ
実行ファ
後者の場合、
イルの
イルのパス名
パス名でなければならず、
でなければならず、それ自身
それ自身が
自身がスクリプトであってはならない
スクリプトであってはならない。
であってはならない。
そしてそれは interpreter [arg] filename の形で呼び出される。
/bin/shの中身も“#!/bin/busybox”にすると、execve()で
シェルスクリプトを呼び出した時に上の条件により、実行できな
い。(initからのスクリプト実行など)
test.sh
execve()
/bin/sh
#!/bin/busybox
#!/bin/sh
…
→ /bin/shのみはリンクにする。
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
9
まとめ
スクリプトラッパの利点
名が体を表わす。
すべて中身は“#!/bin/busybox”15byteのみ
SELinux、及びAppArmorで、ドメイン遷移、アクセ
ス制御の動作を確認(中村さん)
ただし/bin/shのみはリンク
今後
BusyBoxへのスクリプトラッパのパッチ(インストーラ含む)
を本家へ投稿
2007年7月4日
SELinuxユーザ会2007年夏の勉強会
10