カーネル空間でのファイル権限/アクセスの決定はいつ(そしてどのように)行われますか?

カーネル空間でのファイル権限/アクセスの決定はいつ(そしてどのように)行われますか?

私は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-1errnoEACCESwritegetdentsgetdents64

別のターミナルタブ(バイナリの実行時にトリガーされます)で、trace-cmd record -p function_graph -F /bin/ls権限のない同じユーザーとしてTrace-cmdを使用して同じテストを実行すると、デフォルトで私が見るほとんどのシステムコールを1対1にマップできます。 strace および Trace-cmd 出力。/bin/ls /dirtrace-cmdls

ただし、違いは、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_permissiongeneric_permission

おすすめ記事