Un article pas mal sur le logiciel de détection automatique de bugs de Coverity ( http://www.securityfocus.com/print/news/11230(...) ).
J'avais fait une news à l'époque de la détection des plus de 900 bugs du kernel Linux ( http://linuxfr.org/2004/12/17/17904.html(...) ) et voila que maintenant Coverity vient de scruter FreeBSD et de trouver 306 bugs potentiels.
J'ai fait mes petits calculs et si on compare les deux OS on obtient :
Linux 2.6.9 => 5.7 millions de lignes et 985 bugs = 0.17 bugs par milliers de lignes.
FreeBSD => 1.224 millions de lignes et 306 bugs = 0.25 bugs par milliers de lignes...soit 50 % de plus que Linux !
PS : le chiffre de 1.224 millions de lignes pour FreeBSD est obtenu en calculant à partir de l'information de l'article qui indique un bug trouvé pour 4000 lignes (donc 306x4000=1224000).
PS2 : merci de garder un peu d'esprit critique sur tout cet effet d'annonce (Coverity est une société qui veut vendre son produit), sur la nature des bugs (dans le kernel ou juste dans les drivers) et leur danger (accessible par un user ou non).
# ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 6.
Si tu veux le bon nombres de ligne de code utilise sloccount.
"La première sécurité est la liberté"
[^] # Re: ?
Posté par patrick_g (site web personnel) . Évalué à 1.
Humm...oui mais il me faudrait aussi télécharger les sources de FreeBSD donc ma petite multiplication me suffira amplement.
# stats
Posté par ours Ours (site web personnel) . Évalué à 2.
on dira plutot qu'il y a 0,08 points de différence entre les deux ratios.
[^] # Re: stats
Posté par Sylvain Briole (site web personnel) . Évalué à 3.
[^] # Re: stats
Posté par x0ra . Évalué à 3.
[^] # Re: stats
Posté par Sylvain Briole (site web personnel) . Évalué à 2.
[^] # Re: stats
Posté par CoinKoin . Évalué à 2.
Sinon, c'est franchement improbable, ou alors, ce codeur se livre à du piratage.
[^] # Re: stats
Posté par Anonyme . Évalué à 3.
Ce n'est pas du pirtage, mais de la contrefaçon...
[^] # Re: stats
Posté par M . Évalué à 2.
[^] # Re: stats
Posté par Jonathan ILIAS-PILLET (site web personnel) . Évalué à 2.
[^] # Re: stats
Posté par M . Évalué à 5.
[^] # Re: stats
Posté par Prae . Évalué à 2.
[^] # Re: stats
Posté par x0ra . Évalué à 3.
[^] # Re: stats
Posté par Bapt (site web personnel) . Évalué à 1.
[^] # Re: stats
Posté par x0ra . Évalué à 1.
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
C'est le cas pour le nouveau driver reiserfs
ça doit être aussi le cas de l'implémentation de XFS qui utilise les sources sous GPL de SGI.
[^] # Re: stats
Posté par Matthieu Moy (site web personnel) . Évalué à 1.
Dans le cas qui nous est présenté, justement, je trouve ça bien plus pertinent de faire un pourcentage. 0,08 point si c'était entre 50 et 50,08, ça serait une différence mineur, alors qu'entre 0,00017 et 0,00025, je trouve ça assez gros.
[^] # Re: stats
Posté par ours Ours (site web personnel) . Évalué à 6.
si on prend les données brutes, sans réfléchir sur les modes de calcul, ca fait 'uniquement' 100 bugs de différence, et c'est peu vis à vis de l'ensemble référrent (le nombre de lignes). les 50% c'est du spectacle.
n'oublie pas que plus c'est faible, plus ca peut monter rapidement.
si tu n'es pas convaincu, je te prie de me croire que c'est quelque chose qui ne se fait pas trop en statistiques (en tout cas par les gens sérieux)
[^] # Re: stats
Posté par Matthieu Moy (site web personnel) . Évalué à 8.
Mais je t'assure que pour comparer deux proportions, dire "il y a deux fois plus de graisse dans du fromage 40% de matière grasse que dans du 20%", même des gens sérieux s'y autorisent. Comparer des concentrations en faisant des pourcentages, c'est on ne peut plus clair. Si la quantité de tel ou tel gaz toxique dans l'atmosphère est passé de 1ppm a 2ppm d'une année sur l'autre, tu dira que ça a doublé ou que ça a augmenté de 1ppm ?
Dire que pour 100 lignes de code de FreeBSD, coverity trouve 50% plus de bugs que dans 100 lignes de code Linux en moyenne, ça a un sens très clair, et c'est exactement ce que dit le journal.
[^] # Re: stats
Posté par ours Ours (site web personnel) . Évalué à 0.
je dis juste que statistiquement ca n'a pas énormément de sens (volatile etc.).
bref si tu veux l'utiliser, tu le peux c'est ton droit, à toi de voir si tu as envie d'être précis dans ce domaine.
PS:
les comparaisons de matière grasse c'est de l'arnaque.
http://www.tasante.com/sous_rubrique/bien_etre/alimentation/Pages/p(...)
En ce qui concerne les fromages, le taux de matière grasse étant calculés sur la matière sèche, plus ils sont humides et moins il sont gras. Par exemple un fromage blanc à 40% de matière grasse est moins calorique qu’un camembert à 25%
[^] # Re: stats
Posté par Julien Damon (site web personnel) . Évalué à 6.
Dire que Coverity trouve 50 % plus de bugs par lignes de code dans FreeBSD que dans Linux, c'est juste de l'explication de texte (enfin de nombres plutôt :-) )
[^] # Re: stats
Posté par ours Ours (site web personnel) . Évalué à 1.
La statistique est la science et la pratique de la production d'informations à partir de données empiriques quantitatives.
http://fr.wikipedia.org/wiki/Statistiques(...)
[^] # Re: stats
Posté par Julien Damon (site web personnel) . Évalué à 2.
# Un milliard?!
Posté par CoinKoin . Évalué à 7.
Petite remarque : Si tu savais déjà que FreeBSD comportait un bogue (potentiel) pour 4000 lignes, il n'était pas nécessaire de calculer son nombre total de lignes pour en déduire son taux de 0.25 bogues par milliers de lignes.
De plus, nombre de ces soi-disant bogues sont en réalité sans danger. Ainsi, certains dépassements de tableaux dans des cas où l'on est sûr de disposer de la place nécessaire en mémoire.
Autre exemple : dans certains cas, le programmeur a placé des sécurités pour traiter des configurations improbables, mais qu'il ne juge pas impossibles. De son côté, le coverity check détecte que la condition testée ne peut jamais être vraie, et le signale donc comme un bogue. Evidemment, c'est plus qu'inoffensif...
Du coup, ces chiffres peuvent aussi être interprétés comme traduisant une plus grande prudence de la part des programmeurs de FreeBSD.
J'estime donc qu'en tirer une comparaison entre les qualités des deux noyaux est très, très prématuré.
[^] # Re: Un milliard?!
Posté par patrick_g (site web personnel) . Évalué à 2.
pas faux....mais je m'en sort hypocritement en répondant que je voulais une comparaison terme à terme avec le linux 2.6.9 de la news précédente et que donc j'avais besoin du nombre total de lignes.
>> Ainsi, certains dépassements de tableaux dans des cas où l'on est sûr de disposer de la place nécessaire en mémoire.
Je croyais que les BSD se permettaient de baver sur Linux en disant que eux ils codaient proprement et correctement ?
[^] # Re: Un milliard?!
Posté par CoinKoin . Évalué à -1.
Ah, je ne sais pas, je ne suis pas tellement leur activité... En fait, tout ce que je sais, à ce sujet, c'est qu'on m'a dit que le code d'openssh était assez horrible, et que c'était pour ça qu'on n'en faisait pas une bibliothèque.
Cela dit, pour en revenir sur la propreté du code, celui qui suit me semble parfaitement propre, malgré son dépassement :
int i[2];
[...]
/* This is an out-by-one, but it's volunteer, and we are sure there is enough place into memory for it. */
i[2]=0;
[^] # Re: Un milliard?!
Posté par ploum (site web personnel, Mastodon) . Évalué à 9.
Mais c'est absolument dégueulasse ! Et surtout, comment peux-tu être sûr de ton coup ?
Mes livres CC By-SA : https://ploum.net/livres.html
[^] # Re: Un milliard?!
Posté par phoenix (site web personnel) . Évalué à 4.
Je suis sur qu'il doit bien rester un octet en mémoire. Mais suis-je sur que derrière ce tableau, il n'y a pas le code d'un programme qui une fois écraser te feras un bon "Segmentation fault".
En écrivant des programmes en C, j'ai déjà vu des cas ou des dépassement ne faisait pas planté le programme, au moment du dépassement, mais le faisait planté (ou même marché, mais bizarrement, variable modifié, saut dans le code, ....) que beaucoup plus tard.... Et aprés tu passes des heures car tu ne cherches pas au bonne endroit.
[^] # Re: Un milliard?!
Posté par Guinns . Évalué à 1.
On ne peut jamais en être sûr et certain ... je pense plutôt que dans l'exemple, le codeur "sait" que le systeme lui alouera plus que ces 8 octets (sizeof(int) * 2) pour des raisons d'alignement mémoire (32, 64 ...) et qu'à priori, ils resteront "réservés" ...
Ceci dit, je te rejoints complètement sur ton experience de buffer overflow ... je dirais même que le comportement que tu décris et le plus souvent produit.
En effet, un programme peut modifier ses octets partout où il le souhaite sans générer un seul SIGSEGV tant qu'il reste dans sa plage de mémoire réservée par le système ; par contre, par la suite, le programme a en effet de forte chances de planter à un moment ou à un autre parce que ces octets modifiés vont modifier aléatoirement son comportement ... Et on aura notre SIGSEGV parce qu'aléatoirement, on a plus de chance de taper hors sa zone mémoire que dedant :-)
Tiens, ca me rappelle des "challenges informatiques" ... Par exemple, sur un noyau minimum permettant un accés illimité à l'ensemble de la mémoire pour les processus, le but étant de créer un processus capable de corrompre les autres processus tout en assurant sa protection.
Tous les processus sont déclenchés ex-equo et le survivant faisait gagner son codeur.
[^] # Re: Un milliard?!
Posté par Edouard Gomez (site web personnel) . Évalué à 1.
Petite imprécision.
Le programme peut modifier les octets partout où il le souhaite dans ses segments mémoire marqués en écriture (bss/heap/stack etc...) sans générer un seul SIGSEGV.
[^] # Re: Un milliard?!
Posté par CoinKoin . Évalué à 3.
Tous les processus sont déclenchés ex-equo et le survivant faisait gagner son codeur.
Marchera jamais...
<Ce que j'aurais joué>
memset du noyau à la valeur de l'instruction "cli", puis mise d'un joyeux "leave iret" à la fin, et victoire assurée (plus d'interruptions horloge, donc plus de main aux autres processus), à moins de jouer en multiproc.
</Ce que j'aurai joué>
A mon avis, ça devait être des threads ayant un accès illimité à la mémoire utilisateur, mais pas à celle du noyau. Dommage, mais bon...
[^] # Re: Un milliard?!
Posté par Jerome Herman . Évalué à 3.
Ca ce sent
... En fait, tout ce que je sais, à ce sujet, c'est qu'on m'a dit que le code d'openssh était assez horrible
Le mec qui t'a dit ca doit pas suivre tellement leur activité non plus.
et que c'était pour ça qu'on n'en faisait pas une bibliothèque.
On dirait que tu suis pas tellement la sécurisation des clients non plus.
Cela dit, pour en revenir sur la propreté du code, celui qui suit me semble parfaitement propre, malgré son dépassement :
int i[2];
[...]
/* This is an out-by-one, but it's volunteer, and we are sure there is enough place into memory for it. */
i[2]=0;
On en pleurerait
Je préfère quand même
void* i = calloc(2*sizeof(ulong));
int* j= (int*) i;
[...]
j[1] = (int) NULL;
Parceque ca compilera jamais deux fois de la même façon sur deux archis différentes. Même les warnings GCC changent à chaque compilation.... Ce qui est encore plsu drôle c'est la liste d'insultes que sort valgrind.
Bien sur c'est un bonheur pour tous les eptits malins en mal d'attaque par buffer overflow.
Et ca devient encore plus drole quand on passe j[1] en paramêtre d'une fonction.
[^] # Re: Un milliard?!
Posté par Jonathan ILIAS-PILLET (site web personnel) . Évalué à 3.
Pourtant, c'est simple, sémantiquement "int i[2]" ça veut dire allouer 2 int, ça ne dit rien sur ce qu'il y a autour.
Pour les autres situations, ça sera un "int *i;", puis "i[0]" ... "i[2]". Dans ce cas, la définition de "i" indique sans aucune ambiguïté que toi, programmeur, tu t'assures d'accéder là où tu peux le faire.
M'enfin... ce n'est pas parce que le langage C laisse la porte ouverte au code gruick que ça doit devenir la règle.
[^] # Re: Un milliard?!
Posté par CoinKoin . Évalué à 2.
Quatre réponses en une après-midi, chapeau! Bon, je vais vous répondre tous ici, plutôt que de poster quatre réponses.
En fait, le code que j'ai posté n'était là pour faciliter la compréhension du problème, pas pour fournir un exemple concret. Si vous en voulez un, voilà :
http://www.uwsg.iu.edu/hypermail/linux/kernel/0503.3/0957.html(...)
L'exemple que j'ai posté n'en était qu'une version simplifiée. Donc, comme vous le voyez, on peut faire des off-by-one (et pas out-by-one, comme je l'avais écrit précédemment, mea culpa) raisonnablement propres, au point de les intégrer le noyau Linux en toute connaissance de cause.
Pour ma part, j'ai déjà procédé à l'inverse : de magnifiques packet[-1] parsemaient mon code, et je t'assure que c'était parfaitement correct (c'était pour accéder à l'en-tête d'un paquet, dans une pile réseau), et proprement documenté (par l'intermédiaire des commentaires, encore une fois).
Donc, sisisisi, ce style de codage est parfaitement acceptable, il ne casse pas nécessairement la portabilité, ce qui compte, c'est qu'il soit effectué avec précaution, et bien explicité.
En revanche, je veux bien croire que ce genre de choses ne soit jouable qu'en espace noyau, où les informations dont le programmeur dispose sont nettement plus importantes qu'en espace utilisateur (il connait, ou peut connaître, la position physique de son code, le déplacer si nécessaire, kmalloc() alloue toujours des zones mémoires de tailles 2^n, d'où d'autres informations, etc...).
Et pour conclure, les expériences vécues sur des off-by-one involontaires en espace utilisateur ne sont absolument pas transposables à des off-by-one volontaires en espace noyau.
On peut donc parfaitement effectuer des off-by-ones sans commettre de bogue.
[^] # Re: Un milliard?!
Posté par Vivi (site web personnel) . Évalué à 1.
Dans ton exemple, ça veut dire que l'on peut considérer i, i+1, et aussi i+2. Par contre la norme dit bien qu'on a pas le droit de déréférencer le i+2 « If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated. »
Donc, nan, ton i[2] = 0; ne va pas.
Pariel, pour les truc[-1], tout dépend comment tu as obtenu truc. Si c'est comme ça, pas de problèmes :
int *machin = malloc (42 * sizeof (int));
int *truc = machin + 1;
[^] # Re: Un milliard?!
Posté par CoinKoin . Évalué à 2.
Alors, c'est une extension à la norme, parce que, de fait, ça marche. Evidemment, il faut savoir ce qu'on écrase éventuellement, mais ça marche, je viens de le vérifier manuellement en espace utilisateur.
Pariel, pour les truc[-1], tout dépend comment tu as obtenu truc. Si c'est comme ça, pas de problèmes :
[...]
C'était approximativement ça :-) .
[^] # Re: Un milliard?!
Posté par Vivi (site web personnel) . Évalué à 3.
Il est tout à fait possible que ton tableau i soit dans une page où tu as le droit d'écrire et que, pas de bol, i+2 pointe pile sur le début d'une page où tu n'as pas le droit d'écrire. Et là i[2] = 0 ⇒ SIGSEGV.
On pourrait écrire je pense un programme C qui fait ça (avec un peu de mmap()) mais j'ai la flemme :)
[^] # Re: Un milliard?!
Posté par Nicolas Boulay (site web personnel) . Évalué à 3.
Quand tu écris tab[i], le compilo C ne peut pas savoir à tous les coups la taille de tab, pour cela il doit faire une étude global de pointeurs qui n'ira pas forcément loin (paramètre de fonction en int tab[], etc...).
Donc en écrivant tab[i], le compilo comprend prend la base pointé par tab et donne moi le ième élément. Il n'y a aucune notion de taille, et ne te dira jamais rien.
donc tab[i] <=> *(tab+i) (modulo des optimisations possibles)
<=> * (typeof(tab)) ((int)tab + i * sizeof(*tab))
Le segfault ne peut venir que par acces à une mauvaise page mémoire. Les pages système x86, font 4ko. donc si tu alloues 100 octets, tu "un certain nombre" d'octet accessible derrière sans planter. La gestion du malloc empile les bloc mémoires ainsi allouer à la queuelele.
Donc, si tu fais un off by one, tu peux sois écrasé d'autres donnés (super top à debugguer et vive lib efence ou valgrind), soit tomber sur une page interdite et planter.
Le cas du kernel est encore plus violent : il utilise une grosse page de 4Mo : il n'y a _pas_ de protection mémoire dans le kernel.
"La première sécurité est la liberté"
[^] # Re: Un milliard?!
Posté par Sylvain Briole (site web personnel) . Évalué à 3.
Je ne suis pas sûr qu'on puisse jeter l'opprobe sur l'ensemble des noyaux BSD sur ce point : c'est surtout Theo de Raadt qui parle souvent au sujet d'OpenBSD qui met en avant ce point.
NetBSD un peu aussi, mais moins "fortement", eux mettent l'accent sur la propreté du code pas forcément dans un but de sécurité, mais plutôt de portabilité.
Pour FreeBSD, je ne connais pas assez.
# coverity sur coverity ?
Posté par nicodache . Évalué à 10.
[^] # Re: coverity sur coverity ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
"La première sécurité est la liberté"
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.