Question

Je viens de terminer un cours universitaire en C. Je manque donc bien sûr d'expérience.

Certaines universités ont tendance à enseigner à leurs étudiants une programmation sécurisée, ou au moins certains éléments . Il y a même une vidéo ( extrait de ici ).

Être en C, copier des chaînes, nécessite, pour autant que je sache, des fonctions strcpy ou string.h. Comment l'utilisez-vous en toute sécurité dans la programmation quotidienne? Avez-vous des fonctions qui gèrent l’allocation pour empêcher les débordements de mémoire tampon? Il existe le sécurité pour C . Il offre des exemples et des solutions conformes:

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

Et leur alternative est:

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 */
  }
  /* ... */
}

Tiré de cet article, 2ème exemple .

Mais autant que je sache, c'est plus difficile, plus de code, plus de travail. Pourquoi personne ne change la bibliothèque elle-même? Ou du moins, pourquoi personne ne fournit-il une bibliothèque ou des fonctions alternatives sûres, qui gèrent cela correctement?

Merci d'avoir lu, souhait

Était-ce utile?

La solution

The Posix function for this (available on nearly every system) is strdup(). strcpy() is used if you don't want to allocate new memory and already have a buffer you want to use, but then you better known how big that buffer is and if the string fits in it. If you don't know if the string fits, there is strncpy() that just copies a given number of characters. So you can limit the copied amount to your buffers size.

And besides of that, there are lots of sting libraries that manage string sizes in different ways.

And since you tagged it C++: There is std::string that does all the memory management for you and doesn't give you these problems.

Autres conseils

the l (strlcpy, strlcat) functions from OpenBSD are usually better than the n functions, they are both faster and easier to use securely, but they are nonstandard. However, they are BSD licensed so you can include a known good implementation in any program so you can be both cross platform and secure.

For Windows, if you don't care about portability, you can use *_s functions.

Use strncpy:

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

There are *n* versions for most str* functions.

If I understand correctly, your real question is why the API functions are not made more secure.

One reason reason is that C library is legacy (too late to change it now).

The main reason, however, is that the library is designed to be minimalistic, so that it does the bare minimum and it is the user's responsibility to ensure that it is called correctly. If it was doing any excessive checks, then a price would be paid every time it is called, even if the user can assure for other reasons that no problem is going to occur. This is very very common in many APIs.

That being said, there are enough libraries that provide safer alternatives, they're just not part of the standard library. Also, many people who do higher level stuff work with C++, that has standard class libraries for many of those things.

Actually, Microsoft did provide secure alternatives to the CRT functions. Everybody I know hates them though and disables the warning that you shouldn't use the old functions. If you want something secure, maybe you should use C++. And then either STL strings or something like Qt.

Well, or you go to platforms like .NET or Java, which usually doesn't suffer from these problems (your app might crash, but no way to inject code into your app through a buffer overflow).

Edit: With Data Execution Prevention / NX enabled (default for Vista and .NET), this shouldn't be a problem for traditional platforms as well.

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

Maybe you would find useful reading answers to this question

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top