Domanda

Mi piacerebbe essere tranquillamente in grado di simulare con open O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW e O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW su sistemi che non O_NOFOLLOW supporto. Posso in qualche modo ottenere quello che sto chiedendo con:

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

ma poi ho introdurre una condizione di competizione e, eventualmente, un problema di sicurezza.

ho pensato forse la creazione di un file fittizio con solo l'utente di essere in grado di scrivere, un po 'come touching filename, facendo il controllo lstat, e quindi utilizzando chmod dopo finisco di scrivere (per correggere i bit del modo file), ma io potrebbe essere che si affaccia qualcosa di importante (ad esempio se il file in filename esiste, non è un file normale, o è già un link simbolico).

Cosa ne pensi?

È stato utile?

Soluzione

La tua proposta ha ancora una condizione di competizione:

  • Mallory crea il collegamento che vuole a seguire;
  • open() il legame con O_CREAT;
  • Mallory sostituisce il collegamento con un file regolare;
  • Tu fai il test lstat(), che passa (non un collegamento);
  • Mallory sostituisce nuovamente il file regolare con il collegamento.

È possibile risolvere questo problema per il caso non O_TRUNC chiamando fstat() sul descrittore di file aperto come pure lstat() sulla strada, e di garantire che i membri .st_dev e .st_ino sono gli stessi.

Tuttavia, questo non funziona se si sta utilizzando O_TRUNC - per il momento che hai scoperto l'inganno, è troppo tardi -. Mallory ti ha già indotto di troncare uno dei tuoi file importanti

Credo che il modo tradizionale di eliminare la buca senza supporto O_NOFOLLOW è:

  • Creare una directory temporanea con modalità 700. Errore (o tentativi) se mkdir() fallisce a causa di directory esistente;
  • Crea il tuo nuovo file all'interno della directory temporanea;
  • Usa rename() per spostare atomicamente il file temporaneo per il nome di destinazione;
  • Rimuovere la directory temporanea.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top