システムコールの機能を制限するシステムコールtame(2) - OpenBSD 5.8
現段階で最新のOpenBSD安定版のリリースは
tame(2)システムコールを呼んだ後、
# uname -sr OpenBSD 5.8 # man tame | head -20 TAME(2) System Calls Manual TAME(2) NAME tame - restrict system operations SYNOPSIS #include <sys/tame.h> int tame(int flags); DESCRIPTION The current process is forced into a restricted-service operating mode. A few subsets are available, roughly described as computation, memory management, read-write operations on file descriptors, opening of files, networking. In general, these modes were selected by studying the operation of many programs using libc and other such interfaces. Use of tame() in an application will require at least some study and understanding of the interfaces called. #
これはFreeBSDのセキュリティ機能Capsicumによく似ています。よく似ているというか、
I have been working for a while on a subsystem to restrict programs into a "reduced feature operating model". Other people have made such systems in the past, but I have never been happy with them. I don't think I am alone.
Generally there are two models of operation. The first model requires a major rewrite of application software for effective use (ie. capsicum).
ここしばらくの間、
プログラムを 「機能の削減された操作モデル」 へ制限するためのサブシステムの開発を行っています。同様の機能はすでにこれまでほかのオペレーティングシステムで実装されているのですが、 どうも自分にはしっくりきません。そう考えるのは自分だけじゃないと思います。 ざっくりいってこうした操作には2つのモデルがあります。1つ目のモデルだと、
効果的に使用するためにアプリケーションソフトウェアの書き換えが必要になります (Capsicumとか)。
tame(2) WIPより一部抜粋
Theo de Raadt氏はCapsicumの実装を機能を利用するためにソフトウェアへ追加する変更があると指摘しています。Capsicumはケーパビリティと呼ばれるオペレーティングシステムセキュリティ機能の実装系のひとつで、
Capsicumはケーパビリティモデルをかなり洗練された形でPOSIX APIと融合させています。逆に言えば、
tame(2)からpledge(2)システムコールへ変更 - OpenBSD 5.9
Theo de Raadt氏は2015年10月のコミットで、
# uname -sr OpenBSD 5.8 # man pledge /usr/local/man/mandoc.db: No such file or directory man: No entry for pledge in the manual. #
tame(テイム)は飼い慣らす、
#include <sys/tame.h> int tame(int flags);
#include <unistd.h> int pledge(const char *promises, const char *paths[]);
インターフェースの違いを追ってみますと、
11月16日現在、pledge(2)の適用済みコマンドたち
Theo de Raadt氏は2015年11月に送付したメール
ac acpidump addr2line apm apply apropos ar arp as at atq atrm awk b64decode b64encode banner basename batch bc bgpctl bgpd biff c++ c++filt cal cap_mkdb captoinfo cat cc chgrp chmod chown ci cksum clear clri cmp co col colrm column comm compress comsat config cp cpio cpp cron crontab crunchgen csh csplit ctags cu cut date dc dd deroff dev_mkdb df diff diff3prog dig dirname disklabel dmesg doas du dvmrpctl echo ed egrep eigrpctl eigrpd encrypt env ex expand expr fdisk fgen fgrep file find finger fingerd flex flex++ fmt fold from fsck_ext2fs fsck_ffs fsck_msdos fsdb fsirand fstat ftp ftpd fuser g++ gcc gencat getcap getent getopt getty grep group groupadd groupdel groupinfo groupmod groups gunzip gzcat gzip head help hexdump host htpasswd httpd id ident identd ikectl iked indent inetd info infocmp infokey infotocap install-info iscsictl join jot kdump kill ksh kvm_mkdb lam last lastcomm ld ldapctl ldapd ldconfig ldpctl ldpd leave less lesskey lex ln lndir locate locate.bigram locate.code lock lockspool logger login_activ login_crypto login_passwd login_reject login_skey login_snk login_tis login_token login_yubikey logname look ls m4 mailwrapper make makeinfo makewhatis makewhatis man mandoc md5 merge mesg mg mkdir mklocale mktemp more nc ncheck ncheck_ffs netgroup_mkdb nice nl nm nohup nologin nslookup ntpctl ntpd objcopy objdump od opencvs openssl ospf6ctl ospfctl ospfd otp-md5 otp-rmd160 otp-sha1 paste patch pax pflogd pgrep ping ping6 pkill portmap pr printenv printf ps pwd pwd_mkdb radiusctl radiusd radiusd_bsdauth radiusd_radius ranlib rarpd rcs rcsclean rcsdiff rcsmerge rdate readelf readlink rebound relayctl relayd renice reset rev ripctl rksh rlog rm rmdir rmt route route6d rpcgen rs rtadvd savecore scan_ffs scp script sdiff sed sendbug sftp sh sha1 sha256 sha512 signify size skey skeyaudit skeyinfo sleep slowcgi smtpctl smtpd snmpctl sort spamdb spellprog split sshd stat strings strip stty su syslogc syslogd systrace tail tar tcpbench tcpdump tee telnet test texindex tftp tftp-proxy tftpd tic time tmux top touch tput tr traceroute traceroute6 tradcpp tset tsort tty tunefs ul uname uncompress unexpand unifdef uniq units unvis uptime user useradd userdel userinfo usermod users uudecode uuencode vi view vipw vis w wall wc what whatis whereis which who whoami whois write x99token xargs yacc yes ypcat ypldap zcat zdump zegrep zfgrep zgrep zic zzz ZZZ
pledge(2)システムコールは次のように基本的に1行追加するだけとなっています。このあたりはFreeBSD Capsicumも同じです。システムコールを呼ぶことで制限されたモードに入るといった作りになっています。
pledge(2)システムコールの引数のひとつ目は空白区切りの文字列、
void cook_buf(FILE *); void raw_args(char *argv[]); void raw_cat(int); int main(int argc, char *argv[]) { int ch; setlocale(LC_ALL, ""); if (pledge("stdio rpath", NULL) == -1) err(1, "pledge"); while ((ch = getopt(argc, argv, "benstuv")) != -1) switch (ch) { case 'b': bflag = nflag = 1; /* -b implies -n */ break; case 'e': eflag = vflag = 1; /* -e implies -v */ break; case 'n':
まだpledge(2)システムコールが適用されていないコマンドとして次のコマンド一覧も掲載されています。
gMail a2p accton amd amq apmd atactl aucat audioctl authpf authpf-noip gbadsect bgplgsh bioctl calendar cdio chat chfn chio chpass chsh cvs gdhclient dhcpd dhcrelay dump dumpfs dvmrpd edquota eject fdformat fsck gftp-proxy gcov gdb getconf gpioctl gprof growfs hostapd hotplugd gifconfig ifstated init installboot iostat ipcs ipsecctl isakmpd iscsid gkbd keynote kgmon ldattach locale login login_chpass login_lchpass glogin_radius lpc lpf lpq lpr lprm lptest mail mail.local mailx makedbm gmakemap map-mbone memconfig midiplay mixerctl mkalias mkhybrid mknetid gmopa.out mopchk mopd mopprobe moptrace mount mountd mrinfo mrouted gmtrace mtree mv ndp netstat newfs newfs_ext2fs newfs_msdos newsyslog gnfsd nfsstat npppctl npppd nsd nsd-checkconf nsd-checkzone nsd-control gntalkd ospf6d pac passwd pcidump pppstats procmap pstat quot quota gquotacheck quotaoff quotaon radioctl rbootd rdist rdistd rdump grepquota restore revnetgroup ripd rpc.bootparamd rpc.lockd rpc.rquotad grpc.rstatd rpc.rusersd rpc.rwalld rpc.statd rpc.yppasswdd rpcinfo grrestore rup rusers rwall sa sasyncd scsi sensorsd sftp-server gshowmount skeyinit sndiod snmpd spamd spamd-setup spamlogd sqlite3 ssh gssh-add ssh-agent ssh-keygen ssh-keyscan ssh-keysign ssh-pkcs11-helper gstdethers stdhosts swapctl swapon sysctl systat table-ldap gtable-passwd table-sqlite talk trpt unbound unbound-anchor gunbound-checkconf unbound-control unbound-host usbdevs usbhidaction gusbhidctl vacation vmstat vnconfig watchdogd wsconscfg wsconsctl gwsfontload wsmoused ypbind ypmatch yppoll yppush ypserv ypset yptest gypwhich ypxfr
true(1)やhostname(1)のようにソースコードが簡単すぎるものやpledge(2)システムコールの適用ができないコマンドなどは上記一覧には掲載されていないという説明もあります。あまりにシンプルなコマンドはpledge(2)システムコールを適用する意味がほとんどありませんし、
適用対象となるコマンドの66%にpledge(2)システムコールが適用されていることになります。
実装速度の速さとセキュリティ機能の徹底さ
カーネルにおける機能の実装自体はFreeBSDの方が先行していますが、
一方、
OpenBSDの開発チームは規模の上ではFreeBSDの開発チームよりもこぢんまりとしていますが、
FreeBSD CapsicumはGoogle Chromeのセキュリティ機能を実装するにあたって効果的に機能しますが、