バイナリのSUIDビットは依然として「許可拒否」エラーを生成します。

バイナリのSUIDビットは依然として「許可拒否」エラーを生成します。

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バイナリfoo.txtファイル、デフォルトでコマンドを使用して使用された内容を表示しますcat

実行すると、aliceバイナリが正常に実行され、./display-foo内容が表示されます。foo.txtただし、bobrunを実行すると./display-fooバイナリが正常に実行されますが、内容はfoo.txt次のとおりです。見せないでください、エラーが発生します/bin/cat: /home/alice/share/foo.txt: Permission denied


私が理解したところ、setuidビットを設定すると、ファイル所有者(この場合)の権限でバイナリ実行可能ファイルを実行できますalice。それでは、bobコンテンツを見ることができないのはなぜですかfoo.txt


付録: 再コンパイルしましたバイナリgeteuid()有効なユーザーID(EUID)を印刷する機能を使用してください。実際にbobバイナリが実行されるとき、EUIDはalice。しかし、許可が拒否されました。ソースコードの断片は次のとおりです。

printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");

ベストアンサー1

最後まで読んだマニュアルページこのsystem機能の説明を提供する次の段落が見つかりました。

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

display-fooそれでは、この機能を使用するバージョンを作成しましょうsystem

$ 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

display-foosetuidビット設定を含む所有権と権限を設定しましょう。

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

ご覧のとおり、すべてが期待どおりに機能しているようです。

おすすめ記事