alice
とbob
はどちらもstaff
グループに属しています。
次のフォルダがあります。
_drwxrwxr-x 2 alice staff 4096 Oct 30 14:45 share
_
フォルダ内に次のファイルが含まれています。
_-rwsr-xr-x 1 alice alice 8768 Oct 30 14:45 display-foo
-rw------- 1 alice alice 24 Oct 30 14:45 foo.txt
_
_display-foo
_はバイナリファイルであり、cat
コマンドを使用して_foo.txt
_の内容を本質的に表示します。
alice
が_./display-foo
_を実行すると、バイナリファイルが正常に実行され、_foo.txt
_の内容が表示されます。ただし、bob
が_./display-foo
_を実行すると、バイナリファイルは正常に実行されますが、_foo.txt
_の内容は表示されないであり、エラー_/bin/cat: /home/alice/share/foo.txt: Permission denied
_が発生します。
私の理解では、setuidビットを設定すると、バイナリ実行可能ファイルをファイルの所有者(この場合はalice
)の特権で実行できます。それでは、_bob
が_foo.txt
_の内容を表示することを許可されなかったのはなぜですか?
[〜#〜] addendum [〜#〜]:binaryファイルをgeteuid()
関数で再コンパイルして、有効なユーザーを出力するようにしましたID(EUID)。実際、bob
がバイナリファイルを実行すると、EUIDはalice
のEUIDになります。しかし、許可は拒否されました。ソースコードのスニペットを次に示します。
_printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");
_
system
関数の manual page を読み、説明を提供する次の文章に出くわしました。
Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. Use the exec(3) family of functions instead, but not execlp(3) or execvp(3). system() will not, in fact, work properly from programs with set-user-ID or set- group-ID privileges on systems on which /bin/sh is bash version 2, since bash 2 drops privileges on startup. (Debian uses a modified bash which does not do this when invoked as sh.)
以下は、その一節に行く途中で読んだStackExchangeの他の投稿です。
後世のために、そして与えられた例は他の状況でこれまたは同様の問題を診断するのに役立つかもしれないので、私は以下のオリジナルを維持しました。
バグが発生している可能性はありますか? Debian 9とgcc 6.3を実行しているDockerコンテナーで問題を再現できませんでした。これが私があなたの投稿で説明されたシナリオを再現しようと試みた方法です。
最初に「alice」と「bob」のユーザーを作成し、それらを「staff」グループに追加します。
useradd -m -G staff alice
useradd -m -G staff bob
次に、ファイルを作成し、その所有権と権限を設定します。
# Create a subdirectory to hold the text file
Sudo -u alice mkdir -p /home/alice/share/
# Create the text file
Sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'
# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt
結果を確認してみましょう:
$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov 4 15:33 /home/alice/share/foo.txt
次に、system
関数を使用するdisplay-foo
のバージョンを作成します。
$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
int main(int argc, char **argv) {
struct passwd *r_pwd = getpwuid(getuid());
printf("Real user: %s\n", r_pwd->pw_name);
struct passwd *e_pwd = getpwuid(geteuid());
printf("Effective user: %s\n", e_pwd->pw_name);
system("/bin/cat /home/alice/share/foo.txt");
}
HEREDOC
$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo
そして、setuidビットの設定を含め、display-foo
の所有権と権限を設定しましょう。
chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo
結果も確認してみましょう:
$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov 4 15:40 /usr/local/bin/display-foo
次に、プログラムをalice
とbob
の両方として実行します。
$ Sudo -u alice display-foo
Real user: alice
Effective user: alice
This is foo.txt
$ Sudo -u bob display-foo
Real user: bob
Effective user: alice
This is foo.txt
ご覧のとおり、すべてが期待どおりに機能しているようです。
foo.txt
ファイルはAlice home directory
の共有ディレクトリにあるため、権限が原因でボブはAlice home directory
のファイルにアクセスできません。ホームにshared directory
を作成し、このディレクトリにアクセスするための両方の権限を与えることができます。
または、groupowner
の譜表でshared directory
を作成し、次のコマンドでSGID
ビットを設定できます。
chmod 2777 sharedDir
SGID
ビットがディレクトリに設定されている場合、元のディレクトリに作成された新しいファイルまたはサブディレクトリは、ユーザーの現在のデフォルトグループではなく、ディレクトリのグループ所有権を継承します。
したがって、ここでAlice
ファイルを作成すると、ファイルのグループ所有権は[〜#〜] staff [〜#〜]になり、このグループのすべてのメンバーがこれらのファイルにアクセスできますstaff
グループ権限に基づいています。