Domanda

Di recente ho terminato un corso universitario in C. Pertanto, manco di esperienza, ovviamente.

Alcune università tendono a insegnare ai loro studenti una programmazione sicura, o almeno alcuni elementi . C'è persino un video ( tratto da qui ).

Essere in C, copiare stringhe, richiede - per quanto ne so - funzioni strcpy o string.h. Come lo usi in modo sicuro nella programmazione quotidiana? Hai alcune funzioni che gestiscono l'allocazione per prevenire overflow del buffer? C'è il codifica sicura CERT per C . Offre esempi e soluzioni conformi:

int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[128];
  strcpy(prog_name, argv[0]);
  /* ... */
}

E la loro alternativa è:

int main(int argc, char *argv[]) {
  /* ... */
  char *prog_name = (char *)malloc(strlen(argv[0])+1);
  if (prog_name != NULL) {
    strcpy(prog_name, argv[0]);
  }
  else {
    /* Couldn't get the memory - recover */
  }
  /* ... */
}

Tratto da qui, secondo esempio .

Ma per quanto ne so è solo più impegnativo, più codice, più lavoro. Perché nessuno cambia la libreria stessa? O almeno perché nessuno fornisce una libreria o funzioni alternative sicure, che gestiscono ciò nel modo giusto?

Grazie per aver letto, Wishi

È stato utile?

Soluzione

La funzione Posix per questo (disponibile su quasi tutti i sistemi) è strdup(). strcpy() viene utilizzato se non si desidera allocare nuova memoria e si dispone già di un buffer che si desidera utilizzare, ma quindi si sa meglio quanto è grande quel buffer e se la stringa si adatta al suo interno. Se non sai se la stringa si adatta, c'è strncpy() che copia solo un determinato numero di caratteri. Quindi puoi limitare l'importo copiato alla dimensione del tuo buffer.

Inoltre, ci sono molte librerie di sting che gestiscono le dimensioni delle stringhe in diversi modi.

E dato che l'hai taggato C ++: std::string esiste tutta la gestione della memoria per te e non ti dà questi problemi.

Altri suggerimenti

le funzioni l (strlcpy, strlcat) di OpenBSD sono in genere migliori delle funzioni n , sono sia più veloci che più facili da usare in modo sicuro, ma non sono standard. Tuttavia, hanno la licenza BSD in modo da poter includere una buona implementazione nota in qualsiasi programma in modo da poter essere sia multipiattaforma che sicura.

Per Windows, se non ti interessa la portabilità, puoi utilizzare le funzioni * _s.

Usa strncpy :

#define BUFSIZE 127
int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[BUFSIZE + 1];
  strncpy(prog_name, argv[0], BUFSIZE);
  progname[BUFSIZE]= '\0';
  /* ... */
}

Esistono *n* versioni per la maggior parte delle str* funzioni.

Se capisco correttamente, la tua vera domanda è perché le funzioni API non sono rese più sicure.

Uno dei motivi è che la libreria C è legacy (troppo tardi per cambiarla ora).

Il motivo principale, tuttavia, è che la libreria è progettata per essere minimalista, in modo che faccia il minimo indispensabile ed è responsabilità dell'utente assicurarsi che venga chiamata correttamente. Se eseguisse controlli eccessivi, un prezzo verrebbe pagato ogni volta che viene chiamato, anche se l'utente può assicurare per altri motivi che non si verificherà alcun problema. Questo è molto comune in molte API.

Detto questo, ci sono abbastanza librerie che offrono alternative più sicure, semplicemente non fanno parte della libreria standard. Inoltre, molte persone che fanno cose di livello superiore lavorano con C ++, che ha librerie di classi standard per molte di queste cose.

In realtà, Microsoft ha fornito alternative sicure alle funzioni CRT. Tutti quelli che conosco li odiano e disabilitano l'avvertimento che non dovresti usare le vecchie funzioni. Se vuoi qualcosa di sicuro, forse dovresti usare C ++. E poi stringhe STL o qualcosa di simile a Qt.

Bene, o vai su piattaforme come .NET o Java, che di solito non soffrono di questi problemi (la tua app potrebbe bloccarsi, ma non c'è modo di iniettare codice nella tua app attraverso un buffer overflow).

Modifica: Con Data Execution Prevention / NX abilitato (impostazione predefinita per Vista e .NET), questo non dovrebbe essere un problema anche per le piattaforme tradizionali.

int main
(
    int argc, 
    char *argV[]
) 
{
   char prog_name[128];
   if (strlen(argV[0]) < sizeof(prog_name))
   {
       strcpy(prog_name, argV[0]);
   }
   else
   {
       printf("%s is too large for the internal buffer\n", argV[0]);
   }

   return 0;
}

Forse potresti trovare utili risposte di lettura a questa domanda

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top