Question

Je voudrais être en toute sécurité capable de open Simuler avec O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW et O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW sur les systèmes qui ne prend pas en charge O_NOFOLLOW. Je peux un peu réaliser ce que je vous demande avec:

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

mais j'introduire une condition de course et peut-être un problème de sécurité.

Je pensé à créer peut-être un fichier factice avec seul l'utilisateur étant capable d'écrire, un peu comme touching filename, faire le chèque de lstat, puis en utilisant chmod après avoir fini d'écrire (pour corriger les bits de mode de fichier), mais je pourrait être vue sur quelque chose d'important (par exemple si le fichier à filename existe, est pas un fichier régulier, ou est déjà un lien symbolique).

Que pensez-vous?

Était-ce utile?

La solution

Votre proposition a encore une condition de course:

  • Mallory crée le lien qu'il veut vous suivre;
  • Vous open() le lien avec O_CREAT;
  • Mallory remplace le lien avec un fichier régulier;
  • Vous faites votre test lstat(), qui passe (pas de lien);
  • Mallory remplace le fichier régulier avec le lien à nouveau.

Vous pouvez résoudre ce problème pour le cas non O_TRUNC en appelant fstat() sur votre descripteur de fichier ouvert, ainsi que lstat() sur le chemin, et veiller à ce que les membres de .st_dev et .st_ino sont les mêmes.

Cependant, cela ne fonctionne pas si vous utilisez O_TRUNC - le temps que vous avez découvert la supercherie, il est trop tard -. Mallory vous a déjà amené à tronquer un de vos fichiers importants

Je crois que la façon traditionnelle d'éliminer le trou sans support O_NOFOLLOW est:

  • Créez un répertoire temporaire avec le mode 700. Erreur (ou nouvelle tentative) si mkdir() échoue en raison d'annuaire existant;
  • Créez votre nouveau fichier dans le répertoire temporaire;
  • Utilisez rename() pour déplacer atomiquement le fichier temporaire au nom de la cible;
  • Supprimer le répertoire temporaire.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top