
プログラムは開かれたファイル記述子を継承または渡すことができます。そうしないと、ファイルを読み書きできません。たとえば、
(sudo -u nobody echo "hello world") > ~/test-file
(sudo -u nobody cat) < ~/test-file
Q:ユーザーがアクセスできない現在のディレクトリ(またはルートディレクトリ)を継承した場合は、そのディレクトリにアクセスできますか?
答え1
ファイル記述子との比較は非常に間違っています。プロセスの現在のディレクトリとルートディレクトリは、ファイル記述子または「開いたファイル記述」(a)へのポインタではなく、ディレクトリエントリへのポインタにすぎませんstruct file
。struct dentry
カーネルは、現在のディレクトリまたはルートディレクトリが指すディレクトリinodeを参照するオープンファイルの説明を保持せず、子プロセスは任意の種類のハンドルを介してディレクトリinodeを継承できます。
どの方法でも使用するには、他のファイルと同様に、パスを介して現在のディレクトリとルートディレクトリを開く必要があり、すべての標準チェックが適用されます。
ファイルを開くと、O_PATH
不透明なハンドルが返され、成功します。どのファイルパスにアクセスできる場合、読み取りまたは書き込みのためにファイルを正常に開くことはできません。
$ perl -e 'sysopen my $fh, "/root", 0, 0 or die "$!"'
Permission denied at -e line 1.
$ perl -e 'sysopen my $fh, "/root", 010000000, 0 or die "$!"' # 010000000 is O_PATH
$
openat(fd, "", AT_EMPTY_PATH|O_RDWR)
特権プロセスの場合でも、これらの不透明fdは通常のfdとして使用できません。幸いなことに、これをdup()
通常のファイル記述子に変換する方法はありません ;-)
答え2
いいえ。
# sudo -u nobody ls .
ls: cannot access '.': Permission denied
# sudo -u nobody ls -d .
ls: cannot access '.': Permission denied
# chmod o-rwx /chroot
# chroot --userspec=nobody:nobody /chroot
chroot: failed to run command ‘/bin/bash’: Permission denied
現在のディレクトリ(またはルートディレクトリ)への書き込みアクセスも同様です。そうでなければ、これがセキュリティバグの原因になると思います:-).
Linuxで開かれたファイル記述子にも同様の動作が適用されますO_PATH
。
POSIX(未定義O_PATH
)は、openat(fd, path, ...)
同様の機能が開かれたディレクトリにアクセスするための権限を再確認することを意味しますfd
。〜しない限り fd
で開きますO_SEARCH
。 Linuxではサポートされていません。O_SEARCH
。