Il existe un buffer overflow (débordement de tampon) dans mplayer qui, sous certaines conditions, est exploitable à distance. Il est conseillé de patcher.
La version 0.92 et les versions précédant la 0.90pre1 ne sont pas vulnérables. Le patch est disponible sur le site de mplayer.
Enfin, c'est pas grave...tout le monde ne lit pas les journaux...
Extrait du journal : "Bon j'espère que ca n'avait pas déjà été posté avant par qqun d'autre :=)" --> Eh bien non, finalement :)
Quelqu'un aurait-il l'amabilité de me dire en quoi ce code est dangereux?
En fait je ne suis pas trop au courant des technique de programmation permettant d'éviter au maximum les failles. Si vous connaissez une [url] ce serait pas de refus.
Si dans ton site tu mets un lien vers un fichier .avi avec un no; d'hôte super long genre:
www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA....AAAAAAAAAAA.com
ou la suite de A est de longueur assez longure, alors le sprintf ne vas pas tenir dans le buffer de 250, la pile va alors être écrasée sur une distance indéfiniment grande.
Je passe les détails, avec ça, on peut modifier l'adresse de retour pour la faire pointer où on veut. Tu trouvera des expliquations beaucoup plus complètes sur le net ( il y a eu un pdf il y a qq temps qui expliquait bien ça, annoncé sur fr.comp.securite
Pour des explications techniques sur les buffer overflow et les manières des les éviter avec une bonne pratique du codage en C, voir ces 2 documents PDF en français :
le code est dangereux car en C il n'y a pas de vérification de limite : si hostname fait plus que
250 charactères sprintf va continuer a écrire aprés le char str[250].
La chose est encore plus intéressante parceque "aprés" la variable str il y a des donnés comme l'addresse mémoire de retour de la fonction que l'on peut donc changer : on peut charger en mémoire des données et les faire executer.
Comme d'autres l'ont expliqué il s'agit d'un débordement de buffer. Deux méthodes pour éviter ça:
1) vérifier la longueur
char str[250];
snprintf(str, 249, "Host %s:%d", server_url->hostname, server_url->port ); //max 249 caractères
str[249]='\0'; //au cas où - snprintf ne finit pas forcément par le caractère NUL si la chaîne entrée est trop longue
...
snprintf( str, 249, "Host: %s:%d", url->hostname, url->port );
str[249]='\0';
2) allocation dynamique
char *str = NULL; //on alloue ce qu'il faut pour y mettre hostname+"Host :"+15 cars. (on compte large, pour l'entier)
str = (char *)malloc( strlen(server_url->hostname) + strlen("Host :") + 15);
sprintf( str, "Host: %s:%d", server_url->hostname, server_url->port );
...
str = (char *)realloc(str, strlen(url->hostname) + strlen("Host :") + 15);
sprintf( str, "Host: %s:%d", url->hostname, url->port );
Autre solution, arrêter le masochisme et utiliser la glib, char *str=g_strdup_printf ("Host %s:%d", url->hostname, url->port), et voilà un sprintf sans danger et ne nécessitant pas de savants calculs où je me vautrerais une fois sur 2 (faut pas oublier de libérer str après coup quand même)
C'est clair, dans le code C que j'écris pour un projet Gnome, l'utilisation de "g_strdup_printf" simplifie grandement la manipulation des strings et évite de se prendre la tête à tout bout de champ.
Ou encore...
sprintf(str,"Host %230s:%d", server_url->hostname, server_url->port)
Ou meme:
sprintf(str, "Host %*s:%d", 230,server_url->hostname, server_url->port)
Mais pour un respect des GNU Coding Standards, faut faire une allocation dynamique, puisqu'on y dit qu'il vaut mieux eviter les nombres magiques, comme ici ce 250.
Donc:
char *str = NULL;
#define HOST_STRING "Host : %s:%d"
str = malloc(strlen(server_url->hostname) /* ne contient pas le caractere NULL a la fin: c'est un strlen() */
+ sizeof(HOST_STRING) /* contient le caractere NULL a la fin: c'est un sizeof() */
+ 10 /* taille de l'entier */
- 4 /* moins %s%d qui fait 4 caracteres */
);
if(!str) { /* traiter l'erreur. Il faut toujours envisager ce cas */ }
Et une remarque: on ne met pas de (char*) ou autre cast devant un malloc() en C.
machin = malloc() -> c'est du C
machin = (char *)malloc() -> c'est du C++
Je ne sais pas d'ou vient ce reflexe assez courant que de mettre un cast devant le malloc() en C, mais c'est une erreur.
Et si votre compilateur se plaint, c'est que vous avez probablement oublie de mettre #include <stdlib.h>. Rajoutez ce #include <stdlib.h> au lieu de mettre un cast devant le malloc() !
Et une remarque: on ne met pas de (char*) ou autre cast devant un malloc() en C.
Ca depend si tu code en traditionnal ou en c99, car malloc renvoi un void et effectivement le C n'est pas censé raler, mais
1 ca a changé
2 c beaucoup plus propre
T'as raison d'en remettre une couche. A mon tour d'en rajouter :)
Avant, ce cast etait necessaire pour des raisons d'alignement.
Depuis C99, l'alignement est effectue convenablement de toute facon.
Et du coup, je crois que ca repond a ma question, de savoir pourquoi les gens mettent un cast de maniere systematique: c'est tout simplement parce qu'ils ont appris comme ca, avant que la norme soit implementee dans les compilateurs. Je n'avais pas fait le rapprochement :)
Ou alors il y a ceux qui preferent le mettre quand meme pour des raisons d'esth^H^H^H^H^H^Hde lisibilite.
Euh ben en fait, c'est vrai que je lis pas souvent les journaux. Mais en plus, la nouvelle a mis un peu de temps à être modérée (que les modérateurs ne prennent pas ça comme une critique, ils font ce qu'ils peuvent :) ) donc je pense pas avoir posté longtemps après le journal.
# C'était déjà dans les journaux linuxfr le 27/9
Posté par Xavier Brouckaert . Évalué à 5.
Enfin, c'est pas grave...tout le monde ne lit pas les journaux...
Extrait du journal : "Bon j'espère que ca n'avait pas déjà été posté avant par qqun d'autre :=)" --> Eh bien non, finalement :)
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par N-Mi . Évalué à 4.
Quelqu'un aurait-il l'amabilité de me dire en quoi ce code est dangereux?
En fait je ne suis pas trop au courant des technique de programmation permettant d'éviter au maximum les failles. Si vous connaissez une [url] ce serait pas de refus.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Pierre . Évalué à 10.
www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA....AAAAAAAAAAA.com
ou la suite de A est de longueur assez longure, alors le sprintf ne vas pas tenir dans le buffer de 250, la pile va alors être écrasée sur une distance indéfiniment grande.
Je passe les détails, avec ça, on peut modifier l'adresse de retour pour la faire pointer où on veut. Tu trouvera des expliquations beaucoup plus complètes sur le net ( il y a eu un pdf il y a qq temps qui expliquait bien ça, annoncé sur fr.comp.securite
a+
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Marc (site web personnel) . Évalué à 4.
http://lasecwww.epfl.ch/~oechslin/advbof.pdf(...)
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Obsidian . Évalué à 1.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Foxy (site web personnel) . Évalué à 5.
- http://www.k-otik.com/papers/Exploitation_Avancee_BOF.pdf(...)
- http://www.k-otik.com/papers/Bugtraq_Fr_Buffers.pdf(...)
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par ham . Évalué à 7.
250 charactères sprintf va continuer a écrire aprés le char str[250].
La chose est encore plus intéressante parceque "aprés" la variable str il y a des donnés comme l'addresse mémoire de retour de la fonction que l'on peut donc changer : on peut charger en mémoire des données et les faire executer.
Une explication avec schéma en anglais:
http://vulcan.ee.iastate.edu/~cise/instructors/downloads/InterBO/In(...)
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Anonyme . Évalué à 3.
Enfin, des urls de plus de 250 caracteres ...
Pas grand chose a craindre si on a pas rajouté mplayer en plugin pour mozilla.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Alexandre Belloni (site web personnel) . Évalué à 4.
<ASX version = "3.0">
<ENTRY>
<AUTHOR>piout</AUTHOR>
<COPYRIGHT>2003 moi</COPYRIGHT>
<TITLE>ma video</TITLE>
<ref href="mms://mms.piout.net/matreslongueurlquivafaireexplosertonmplayer.wmv"/>
</ENTRY>
</ASX>
avec une url encore plus longue.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Colin Leroy (site web personnel) . Évalué à 9.
1) vérifier la longueur
char str[250];
snprintf(str, 249, "Host %s:%d", server_url->hostname, server_url->port ); //max 249 caractères
str[249]='\0'; //au cas où - snprintf ne finit pas forcément par le caractère NUL si la chaîne entrée est trop longue
...
snprintf( str, 249, "Host: %s:%d", url->hostname, url->port );
str[249]='\0';
2) allocation dynamique
char *str = NULL;
//on alloue ce qu'il faut pour y mettre hostname+"Host :"+15 cars. (on compte large, pour l'entier)
str = (char *)malloc( strlen(server_url->hostname) + strlen("Host :") + 15);
sprintf( str, "Host: %s:%d", server_url->hostname, server_url->port );
...
str = (char *)realloc(str, strlen(url->hostname) + strlen("Host :") + 15);
sprintf( str, "Host: %s:%d", url->hostname, url->port );
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Christophe Fergeau . Évalué à 10.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Foxy (site web personnel) . Évalué à 1.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Daniel Caujolle-Bert . Évalué à 1.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Ano nyme (site web personnel) . Évalué à 0.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Olivier Jeannet . Évalué à 2.
je te conseille d'ailleurs vivement de désinstaller cette librairie si peu utile :-))
Je crois que tu confonds la glib avec la libc (autrement connue comme "glibc" quand il s'agit de celle de GNU)
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par a_jr . Évalué à 6.
sprintf(str,"Host %230s:%d", server_url->hostname, server_url->port)
Ou meme:
sprintf(str, "Host %*s:%d", 230,server_url->hostname, server_url->port)
Mais pour un respect des GNU Coding Standards, faut faire une allocation dynamique, puisqu'on y dit qu'il vaut mieux eviter les nombres magiques, comme ici ce 250.
Donc:
Et une remarque: on ne met pas de (char*) ou autre cast devant un malloc() en C.
machin = malloc() -> c'est du C
machin = (char *)malloc() -> c'est du C++
Je ne sais pas d'ou vient ce reflexe assez courant que de mettre un cast devant le malloc() en C, mais c'est une erreur.
Et si votre compilateur se plaint, c'est que vous avez probablement oublie de mettre #include <stdlib.h>. Rajoutez ce #include <stdlib.h> au lieu de mettre un cast devant le malloc() !
Le bonjour chez vous,
Yves
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 4.
Ca depend si tu code en traditionnal ou en c99, car malloc renvoi un void et effectivement le C n'est pas censé raler, mais
1 ca a changé
2 c beaucoup plus propre
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par a_jr . Évalué à 3.
Avant, ce cast etait necessaire pour des raisons d'alignement.
Depuis C99, l'alignement est effectue convenablement de toute facon.
Et du coup, je crois que ca repond a ma question, de savoir pourquoi les gens mettent un cast de maniere systematique: c'est tout simplement parce qu'ils ont appris comme ca, avant que la norme soit implementee dans les compilateurs. Je n'avais pas fait le rapprochement :)
Ou alors il y a ceux qui preferent le mettre quand meme pour des raisons d'esth^H^H^H^H^H^Hde lisibilite.
Yves
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Christophe Morvan (site web personnel) . Évalué à 7.
Et oui.
Extrait du journal : "Bon j'espère que ca n'avait pas déjà été posté avant par qqun d'autre :=)" --> Eh bien non, finalement :)
Les gens qui lisent les journaux lisent aussi les niouses : il est donc stupide de repasser sous forme d'un journal le contenu d'une nouvelle.
En revanche très nombreux sont ceux qui ne lisent que les nouvelles... il n'est donc pas stupide, pour une dépèche, de reprendre un journal.
Au passage, les niouse sont modérées, elle bénéficient donc également d'un plus grand crédit.
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Anonyme . Évalué à 1.
c'est comme le mot oueb...
Bon oké ~>[]
[^] # Re: C'était déjà dans les journaux linuxfr le 27/9
Posté par Alexandre Belloni (site web personnel) . Évalué à 3.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.