Frage

Ich möchte sicher mit open und O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW auf Systeme zu simulieren O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW der Lage sein, die keine Unterstützung O_NOFOLLOW tun. Ich kann etwas erreichen, was ich frage für mit:

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);

aber dann stelle ich eine Race-Bedingung und möglicherweise ein Sicherheitsproblem.

Ich dachte vielleicht eine Dummy-Datei erstellen mit nur dem Benutzer zu schreiben in der Lage, die Art wie touch filenameing, tut der lstat Prüfung und dann chmod verwenden, nachdem ich fertig zu schreiben (die Datei Modusbits zu korrigieren), aber ich mit Blick auf etwas Großes werden könnte (existiert zB wenn die Datei bei filename, keine reguläre Datei ist, oder ist bereits ein symbolischer Link).

Was denken Sie?

War es hilfreich?

Lösung

Your proposal still has a race condition:

  • Mallory creates the link he wants you to follow;
  • You open() the link with O_CREAT;
  • Mallory replaces the link with a regular file;
  • You do your lstat() test, which passes (not a link);
  • Mallory replaces the regular file with the link again.

You can fix this for the non-O_TRUNC case by calling fstat() on your open file descriptor as well as lstat() on the path, and ensuring that the .st_dev and .st_ino members are the same.

However, this doesn't work if you're using O_TRUNC - by the time you've discovered the deception, it's too late - Mallory has already induced you to truncate one of your important files.

I believe the traditional way to eliminate the hole without O_NOFOLLOW support is:

  • Create a temporary directory with mode 700. Error (or retry) if mkdir() fails due to existing directory;
  • Create your new file within the temporary directory;
  • Use rename() to atomically move the temporary file to the target name;
  • Remove the temporary directory.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top