bionic (7) path_resolution.7.gz
![bug](/img/bug.png)
名前
path_resolution - ファイルのパス名の解決方法
説明
いくつかの UNIX/Linux システムコールは、 1 つ以上のファイル名を引き数として持つ。 ファイル名 (またはパス 名) は以下のようにして解決される。 ステップ 1: 解決過程を開始する パス名が '/' 文字で始まっている場合、 ディレクトリ検索の開始点は呼び出し元のプロセスのルートディレクトリ になる。 (プロセスはルートディレクトリを親プロセスから継承する。 通常は、これがファイル階層のルートディレ クトリになる。 プロセスは chroot(2) システムコールを使って別のルートディレクトリを取得することもできる。 この場合、そのプロセスと CLONE_NEWNS フラグを設定して clone(2) を呼び出すことによって開始されたそのプロ セスの子孫は、 完全にプライベートなマウント名前空間を取得できる。) パス名の '/' の部分は、このようにして 扱われる。 パス名が '/' 文字で始まっていない場合、 解決過程におけるディレクトリ検索の開始点は、 プロセスの現在の作業 (working) ディレクトリとなる。 (これも親プロセスから継承される。 これは chdir(2) システムコールを使うこ とで変更できる。) '/' 文字で始まるパス名は絶対パス名と呼ばれ、 '/' 文字で始まらないパス名は相対パス名と呼ばれる。 ステップ 2: パスを辿る 現在の検索ディレクトリをディレクトリ検索の開始点とする。 そして、パス名の最後の構成要素 (component) でな い各構成要素について、 現在の検索ディレクトリで検索を行う。 ここで構成要素は '/' で区切られた部分文字列で ある。 プロセスが現在の検索ディレクトリの検索許可を持たない場合、 EACCES エラーが返される ("Permission denied")。 構成要素が見つからない場合、 ENOENT エラーが返される ("No such file or directory")。 構成要素は見つかったが、ディレクトリでもシンボリックリンクでもない場合、 ENOTDIR エラーが返される ("Not a directory")。 構成要素が見つかって、かつディレクトリである場合、 現在の検索ディレクトリをそのディレクトリに設定し、 次 の構成要素に移動する。 構成要素が見つかって、かつシンボリックリンク (symlink) である場合、 (現在の検索ディレクトリをディレクトリ 検索の開始点として) 最初にそのシンボリックリンクを解決する。 結果がディレクトリでない場合、 ENOTDIR エ ラーが返される。 シンボリックリンクの解決が成功してディレクトリが返された場合、 そのディレクトリを現在の 検索ディレクトリとして設定し、 次の構成要素に移動する。 解決過程に再帰が含まれる点に注意すること。 カーネ ルをスタックオーバーフローや サービス拒否 (denial of service) から守るため、 再帰の最大の深さとシンボリッ クリンクを辿る最大回数に制限がある。 最大値を超えた場合 ELOOP エラーが返される ("Too many levels of symbolic links")。 ステップ 3: 最後のエントリーを見つける パス名の最後の構成要素の検索は、前のステップで説明した 他の全ての構成要素と同じように実行されるが、2 つの 違いがある。 (i) 最後の構成要素はディレクトリである必要がない (パス解決過程に関する限りはどちらでも構わな い — 特定のシステムコールが要求するものによって、 ディレクトリでなければならない場合もあるし、 ディレクト リ以外でなければならない場合もある)。 (ii) 構成要素が見つからない場合にエラーにする必要はない — その構成 要素を作成するだけでよい場合もある。 最後のエントリーの詳細な扱いは、 特定のシステムコールの man ページで 説明されている。 . と .. 慣習として、全てのディレクトリはエントリー "." と ".." を持つ。 これらはそれぞれ、そのディレクトリ自身と その親ディレクトリを参照する。 パス解決過程では、これらのエントリーが物理的なファイルシステムに 実際に存在するか否かに関わらず、慣習的な 意味を持つと仮定する。 ルートより上に辿ることはできない: "/.." は "/" と同じである。 マウント位置 "mount dev path" コマンドを実行した後、 パス名 "path" はデバイス "dev" 上のファイルシステム階層の ルート ディレクトリを参照するようになり、以前の位置を参照しない。 マウントされたファイルシステムの外に出ることができる: "path/.." は "dev" 上のファイルシステム階層の外であ る "path" の親ディレクトリを参照する。 末尾のスラッシュ パス名が '/' で終わっている場合、 ステップ 2 において、その前にある構成要素の解決法を次のように強制する: その構成要素が存在しなければならず、ディレクトリとして解決される。 存在しない場合は、末尾の '/' が無視さ れる。 (また同様に、末尾に '/' があるパス名は、 '.' を末尾に加えて得られるパス名と等しい。) 最後がシンボリックリンクのとき パス名の最後の構成要素がシンボリックリンクである場合、 参照されるファイルをシンボリックリンクとするか、 その内容についてパスを解決した結果とするかは、 システムコールに依存する。 たとえば、システムコール lstat(2) はシンボリックリンクに作用する。 一方、 stat(2) はシンボリックリンクで指されたファイルに作用す る。 長さの制限 パス名には最大長がある。 パス名 (またはシンボリックリンクを解決するときに得られる中間パス名) が 長すぎる 場合、 ENAMETOOLONG エラーが返される ("Filename too long")。 空のパス名 元々の UNIX では、空のパス名は現在のディレクトリを参照していた。 最近、POSIX では空のパス名を解決するべき ではないという決定がなされた。 この場合、Linux は ENOENT を返す。 許可 ファイルの許可ビットは、3 組の 3 ビットから構成される。 chmod(1) と stat(2) を参照すること。 呼び出し元 のプロセスの実効ユーザー ID がファイルの所有者 ID と等しい場合、 3 つのうち最初のグループが使われる。 ファイルのグループ ID が呼び出し元のプロセスの実効グループ ID または (setgroups(2) で設定される) 呼び出 し元のプロセスの補助 (supplementary) グループ ID と 等しい場合、3 つのうち 2 番目のグループが使われる。 どちらにも当てはまらない場合、3 番目のグループが使われる。 3 ビットが使われる場合、最初のビットは読み込み許可を決定し、 2 番目のビットは書き込み許可を決定する。 ま た 3 番目のビットは、通常のファイルの場合は実行許可を表し、 ディレクトリの場合は検索許可を表す。 Linux は、許可のチェックにおいて、実効ユーザー ID ではなく fsuid を使う。 通常は fsuid は実効ユーザー ID と等しいが、fsuid はシステムコール setfsuid(2) で変更することができる。 (ここで "fsuid" は "file system user ID" を表している。 この概念は「プロセスが同じ実効ユーザー ID を持つ プロセスに 同時にシグナルを送ることができる」というユーザー空間 NFS サーバを 実装する際に必要であった。 これは今では廃れてしまった。 setfsuid(2) を使うべきではない。 同様に、Linux では実効グループ ID の代わりに fsgid ("ファイルシステムグループID") を使う。 setfsgid(2) を 参照すること。 許可の確認をスキップする: スーパーユーザーとケーパビリティ 伝統的な UNIX システムでは、スーパーユーザー (root, ユーザー ID 0) は非常に強力であり、ファイルアクセス時 の 許可による制限を全てスキップする。 Linux では、スーパーユーザー権限が複数のケーパビリティに分割されている (capabilities(7) 参照)。ファイルの 許可の確認には、 CAP_DAC_OVERRIDE と CAP_DAC_READ_SEARCH の 2つのケーパビリティが関係する (プロセスの fsuid が 0 の場合、そのプロセスはこれらのケーパビリティを持つ)。 CAP_DAC_OVERRIDE ケーパビリティは全ての許可チェックを上書きする。 実際には、対象となるファイルの 3 つの実 行許可ビットのうちの 少なくとも 1 つが設定されている場合のみ、実行を許可する。 CAP_DAC_READ_SEARCH ケーパビリティは、ディレクトリに対して読み込みと検索を許可し、 通常のファイルに対して 読み込みを許可する。
関連項目
readlink(2), capabilities(7), credentials(7), symlink(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告 に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。