%20%E3%81%8C%E5%A4%B1%E6%95%97%20%2F%20%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E5%A4%89%E6%9B%B4%3F.png)
最近 CentOS 6.4 にアップデートした後、2 台のマシンに、capabilities または selinux のように動作する setuid() 制限がありますが、両方とも無効になっています。たとえば、次のコードは失敗します。
[root@host statd]# perl -e 'use POSIX; POSIX::setuid(99);system("id")'
[root@host statd]# echo $?
0
次のような結果が返されるはずです:
host:~# perl -e 'use POSIX; POSIX::setuid(99);system("id")'
uid=99(nobody) gid=0(root) groups=99(nobody),0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
perl の呼び出しを strace すると、setuid() 呼び出しは成功しますが、system() 子プロセスは、selinux などによって終了されたかのように、すぐに終了します。ただし、semodule -DB を実行した後でも、/var/log/audit/audit.log にログ エントリはありません。
setuid32(99) = 0
getuid32() = 99
geteuid32() = 99
pipe([3, 4]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7705728) = 10073
close(4) = 0
rt_sigaction(SIGINT, {SIG_IGN, [], 0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [], 0}, {SIG_DFL, [], 0}, 8) = 0
waitpid(10073, [{WIFEXITED(s) && WEXITSTATUS(s) == 255}], 0) = 10073
--- SIGCHLD (Child exited) @ 0 (0) ---
rt_sigaction(SIGINT, {SIG_DFL, [], 0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], 0}, NULL, 8) = 0
read(3, "\r\0\0\0", 4) = 4
close(3) = 0
exit_group(0)
この問題は、最初の再起動後に nfs.statd が「ローカル netconfig データベースにアクセスできませんでした: Netconfig データベースが見つかりません」というエラーで失敗したことで明らかになりました。また、rpc.rquotasd は「RPC: サーバー localhost にはより強力な認証が必要です」というエラーで失敗しました。
nfs.statd の問題は、root として実行することで解決できます (chown root:root /var/lib/nfs/statd)。マシン上のすべてを root として実行することは、あまり良い回避策ではないようです。;)
別のアカウントに su しようとしても機能しません。
[root@host ~]# su - jboss
su: warning: cannot change directory to /opt/jboss: Permission denied
su: /bin/bash: Permission denied
[root@host ~]# su jboss
su: /bin/bash: Permission denied
基本的なシステム情報は次のとおりです。
[root@host statd]# getenforce
Permissive
[root@host statd]# uname -a
Linux host.example.com 2.6.32-358.14.1.el6.i686 #1 SMP Tue Jul 16 21:12:30 UTC 2013 i686 i686 i386 GNU/Linux
[root@host statd]# cat /etc/redhat-release
CentOS release 6.4 (Final)
[root@host statd]# getcap /usr/bin/perl
/usr/bin/perl =
明らかに selinux や Linux の機能ではないのに、この原因は何でしょうか?
答え1
何らかの理由で、アップグレード プロセスによって / の権限が次のように変更されました:
[root@host ~]# ls -alZ /
drw-r--r--. 42374 5031 system_u:object_r:root_t:s0 .
drw-r--r--. 42374 5031 system_u:object_r:root_t:s0 ..
これは、
chown root:root / && chmod 755 /
エラースペースを狭めるのに大きく役立ったのは、代わりに実行した
strace perl -e 'use POSIX; POSIX::setuid(99);exec("id")'
これは、perl の execve() 呼び出しがすべての $PATH ディレクトリを試行するたびに EACCES で失敗することを示しました。