私は、ファイル機能を使用して、setuid-rootバイナリ(たとえば/bin/ping
、CAP_NET_RAWなど)の必要性のほとんどを排除するGentoo Hardenedボックスを管理しています。
実際、私が残した唯一のバイナリはこれです:
abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ #
setuidビットを削除するか、ルートファイルシステムを再マウントするnosuid
と、sshdとGNU Screenが動作を停止しますgrantpt(3)
。これらはマスターの擬似端末を呼び出し、glibcはこのプログラムを実行してスレーブの擬似端末をchownおよびchmodする/dev/pts/
ためです。失敗します。
問題は、grantpt(3)
Linuxの場合、devpts
ファイルシステムがマウントされていると、そのようなヘルパーバイナリは不要であると明示的に記載されているマンページです。カーネルは、スレーブのUIDとGIDを、/dev/ptmx
(呼び出しによりgetpt(3)
)開いたプロセスの実際のUIDとGIDに自動的に設定します。
これを示すために、小さなサンプルプログラムを作成しました。
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int master;
char slave[16];
struct stat slavestat;
if ((master = getpt()) < 0) {
fprintf(stderr, "getpt: %m\n");
return 1;
}
printf("Opened a UNIX98 master terminal, fd = %d\n", master);
/* I am not going to call grantpt() because I am trying to
* demonstrate that it is not necessary with devpts mounted,
* the owners and mode will be set automatically by the kernel.
*/
if (unlockpt(master) < 0) {
fprintf(stderr, "unlockpt: %m\n");
return 2;
}
memset(slave, 0, sizeof(slave));
if (ptsname_r(master, slave, sizeof(slave)) < 0) {
fprintf(stderr, "ptsname: %m\n");
return 2;
}
printf("Device name of slave pseudoterminal: %s\n", slave);
if (stat(slave, &slavestat) < 0) {
fprintf(stderr, "stat: %m\n");
return 3;
}
printf("Information for device %s:\n", slave);
printf(" Owner UID: %d\n", slavestat.st_uid);
printf(" Owner GID: %d\n", slavestat.st_gid);
printf(" Octal mode: %04o\n", slavestat.st_mode & 00007777);
return 0;
}
前述のプログラムのsetuidビットを削除して、動作を観察します。
aaron@abraxas ~ $ id
uid=1000(aaron) gid=100(users) groups=100(users)
aaron@abraxas ~ $ ./ptytest
Opened a UNIX98 master terminal, fd = 3
Device name of slave pseudoterminal: /dev/pts/17
Information for device /dev/pts/17:
Owner UID: 1000
Owner GID: 100
Octal mode: 0620
この問題を回避する方法については、いくつかのアイデアしかありません。
1)プログラムを、単に0を返すスケルトンに置き換えます。
2)libcでgrantpt()をパッチして何もしない。
私はこれらの両方を自動化できますが、誰かが他のものよりも推奨事項、またはこれを解決する他の方法について推奨事項がありますか?
これが解決したら、ようやくできmount -o remount,nosuid /
ます。
pty
(必要なように)ではなくプログラムをチェックしていますか?