私はLinux権限がどのように機能するか(既存のUnix DAC権限と表示方法、プロセス関連のセキュリティコンテキスト(資格情報構造、機能など)、LSMフックなど)について比較的よく理解しています。 (E)UID / E(GID)などへのリンク私が理解しておらず、カーネルコードで見つけるのが難しいのは、ftrace
(pass trace-cmd
)を使用してこれらのチェックが実際にカーネル空間で(おそらく)実行されるときです。どのポイント実際にアクセス決定が下されます。
詳細な説明:
/dir
ルートchmodが所有するディレクトリがありますr-x------
(500)。権限のないユーザーとして実行しましたが、期待/bin/ls /dir
どおりに権限拒否エラーが発生しました。
実行すると、ユーザースペースに戻り(「Permission Denied」など)に設定されたシステムコールをstrace -s 10000 /bin/ls /dir
表示できます。その後、STDERRにエラーメッセージを出力する後続のシステムコールがあり、すべてが期待どおりに機能します。私はここでシステムコールを見たり電話したことがありません。open
-1
errno
EACCES
write
getdents
getdents64
別のターミナルタブ(バイナリの実行時にトリガーされます)で、trace-cmd record -p function_graph -F /bin/ls
権限のない同じユーザーとしてTrace-cmdを使用して同じテストを実行すると、デフォルトで私が見るほとんどのシステムコールを1対1にマップできます。 strace および Trace-cmd 出力。/bin/ls /dir
trace-cmd
ls
ただし、違いは、open
システム呼び出し後のTrace-cmd出力で書き込み出力とその終了を見るのではなく呼び出しがgetdents
行われるのを見ることです(そして、繰り返しディレクトリ内の項目の完全な呼び出しツリーなど)。 。 。私の考えでは、ftraceの制限(および私の理解による制限の可能性)のために出力でシステムコールの引数や戻り値を見ることができないため、許可エラーがいつ発生するのかわかりません。しかし、私の限られた理解によると、カーネルは実際にディレクトリの完全なリストを実行しますが、出力をユーザー空間に返さないようです。
それでは、実際に何が起こっているのかを説明できる人はいますか?trace-cmd
カーネルが実際にgetdents
システムコールを実行していますが、strace
オープンコールが失敗した後に終了するのはなぜですか?権限に関する問題に対処するほとんどのフォーラム投稿(ここや他の場所)では、ファイルを開くときに確認することをお勧めしますが、詳細は提供しません。これは私が見たものと一致しますがstrace
(しかしftrace
/ではありませんtrace-cmd
)。
カーネルソースを見てopen
/ systemcallsでopenat
手動で追跡すると、inode_permission -> do_inode_permission -> generic_permission -> acl_permission_check
後者は実際にクラシックUnix権限を比較し、それから返されるような一連の関数呼び出しを見ることができます。また、SELinux、Apparmor、SMACK、Tomoyoなどの他の場所でもLSMのフックを見ることができ、それらが機能すると想像しています。
私の仮定は、ディレクトリを開こうとすると権限チェックが発生し、カーネルが「いいえ」と言い、ユーザー空間にエラーが返され、実際にディレクトリリストを実行するポイントに到達できないことです。しかし、出力によると、trace-cmd
ディレクトリのリストが実際に発生しているように見えますが、もはやわかりません。
できるだけ技術的に深い情報を提供していただきありがとうございます。また、Systemtapを使用すると、より多くの情報を得ることができることを知っていますが、これについて私が知っていること非常に限定!
認知度を高めるために、Debianベースのディストリビューションでカーネルバージョン2.6.35と6.5.0をテストしましたが、結果は比較的似ていました。
答え1
ユーザーエラーと理解不足trace-cmd
(特に-F
私が使用するフラグ)が問題です。
私の前提は、実行中に "ls"プロセスが実行されるのを見るのを待って接続することtrace-cmd record -p function_graph -F /bin/ls
です。trace-cmd
これにより、-F
バイナリがそこにあり、実行されます(ルートtrace-cmd
として実行されることを考慮すると、ルートとして)。ハッキーな解決策は、私がプロセスに接続されていることを確認することでした。いくつかの醜いCは、プロセスのPIDを取得しながら数秒間スリープ状態を維持し、プロセスがユーザーls
として実行されるようにしました。これにより、すべてが期待されます。私はもともと理解した内容が正しいことを確認できました。
open
注:権限チェックは、システムコールの関数呼び出しチェーンに沿ってファイルを開くときに行われます。いくつかのコードは最初に空のファイル記述を割り当て、構造のビットを埋め始めます。実際の権限チェックは、呼び出しチェーンの終わりに発生するようです。ディレクトリオブジェクトの場合、実行権限を確認するための専用コードがあります。次に、基本的なDACチェックを実行する関数may_open
を呼び出します。ここにもLSMチェックがあります。これが失敗すると、期待どおりに権限エラーが返されます。inode_permission
generic_permission