1

をサポートしていないシステムでopen安全にシミュレートできるようにしたいと考えO_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOWています。私が求めていることをある程度達成することができます:O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOWO_NOFOLLOW

struct stat lst;
if (lstat(filename, &lst) != -1 && S_ISLNK(lst.st_mode)) {
    errno = ELOOP;
    return -1;
}

mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, mode);

しかし、競合状態が発生し、セキュリティ上の問題が発生する可能性があります。

touchユーザーだけが書き込むことができるダミーファイルを作成することを考えましたingのようなものでfilenamelstatチェックを行い、chmod書き込みが終了した後に使用します(ファイルモードビットを修正するため)が、何か大きなものを見落とす可能性があります(たとえば、ファイルがfilename存在する場合、通常のファイルではない場合、または既にシンボリック リンクである場合)。

どう思いますか?

4

1 に答える 1

4

あなたの提案にはまだ競合状態があります:

  • Mallory は、あなたにたどってもらいたいリンクを作成します。
  • あなたopen()とのリンクO_CREAT;
  • Mallory は、リンクを通常のファイルに置き換えます。
  • テストを行いますlstat()が、これはパスします (リンクではありません)。
  • Mallory は通常のファイルを再びリンクに置き換えます。

開いているファイル記述子とパスをO_TRUNC呼び出し、とメンバーが同じであることを確認することで、大文字と小文字を区別しない場合にこれを修正できます。fstat()lstat().st_dev.st_ino

ただし、使用している場合、これは機能しません。O_TRUNC詐欺に気付いたときには手遅れです。マロリーは、重要なファイルの 1 つを切り捨てるように既に誘導しています。

O_NOFOLLOWサポートなしで穴をなくす従来の方法は次のとおりだと思います。

  • mode で一時ディレクトリを作成します700mkdir()既存のディレクトリが原因で失敗した場合はエラー (または再試行) 。
  • 一時ディレクトリ内に新しいファイルを作成します。
  • rename()一時ファイルをターゲット名にアトミックに移動するために使用します。
  • 一時ディレクトリを削除します。
于 2010-05-26T23:08:39.353 に答える