Le bogue des nombres à virgule flottante refait surface en Java
Il plonge le compilateur et les programmes dans des boucles infinies
Le 2011-02-08 13:23:03, par Idelways, Expert éminent sénior
Mise à jour du 08/02/2011
Quelque temps après sa correction sur PHP, le bogue étrange des nombres à virgule flottante refait surface sur un langage tout aussi populaire : Java.
Ce bogue provoquait sur PHP avant sa correction le crash du système par le passage d'un simple paramètre dans l'URL, pour peu que le script convertisse en nombres ou utilise ces variables dans des opérations arithmétiques (pour plus de détails, lire ci-devant)
Sur Java, un bogue similaire plongerait les programmes à l'exécution (ou leur compilateur) dans des boucles infinies d'après Exploring Binary, le site où ont été mis en lumière les deux bogues.
Le nombre en question, le désormais célèbre 2.2250738585072012e-308 et ses différentes représentations sont supposés être convertie en 0x1p-1022, qui correspond à la constante DBL_MIN.
Au lieu de cela, Java se retrouve coincé, oscillant sans arrêt entre les valeurs 0x1p-1022 et 0x0.fffffffffffffp-1022, le plus grand nombre dénormalisé à double précision et à virgule flottante.
Le bogue serait provoqué par la boucle de correction de la classe FloatingDecimal, chargée de trouver la meilleure approximation, qui la trouve mais la remplace et la retrouve infiniment...
Le bogue a été reporté à Oracle depuis plusieurs semaines, son rapport a récemment été assigné pour analyse interne non accessible sur Sun Developer Network (SDN).
Pour reproduire ce bogue à l'exécution des programmes, compilez et exécutez ce programme
Pour provoquer une boucle infinie au niveau du compilateur, il suffit de tenter de compiler cette classe :
Source : Exploring Binary
Et vous ?
Arrivez-vous à reproduire ce bug ?
Sur quelle plateforme, architecture et version de JRE/JDK ?
Quelque temps après sa correction sur PHP, le bogue étrange des nombres à virgule flottante refait surface sur un langage tout aussi populaire : Java.
Ce bogue provoquait sur PHP avant sa correction le crash du système par le passage d'un simple paramètre dans l'URL, pour peu que le script convertisse en nombres ou utilise ces variables dans des opérations arithmétiques (pour plus de détails, lire ci-devant)
Sur Java, un bogue similaire plongerait les programmes à l'exécution (ou leur compilateur) dans des boucles infinies d'après Exploring Binary, le site où ont été mis en lumière les deux bogues.
Le nombre en question, le désormais célèbre 2.2250738585072012e-308 et ses différentes représentations sont supposés être convertie en 0x1p-1022, qui correspond à la constante DBL_MIN.
Au lieu de cela, Java se retrouve coincé, oscillant sans arrêt entre les valeurs 0x1p-1022 et 0x0.fffffffffffffp-1022, le plus grand nombre dénormalisé à double précision et à virgule flottante.
Le bogue serait provoqué par la boucle de correction de la classe FloatingDecimal, chargée de trouver la meilleure approximation, qui la trouve mais la remplace et la retrouve infiniment...
Le bogue a été reporté à Oracle depuis plusieurs semaines, son rapport a récemment été assigné pour analyse interne non accessible sur Sun Developer Network (SDN).
Code : |
1 2 3 4 5 6 7 | class runhang { public static void main(String[] args) { System.out.println("Test:"); double d = Double.parseDouble("2.2250738585072012e-308"); System.out.println("Value: " + d); } } |
Code : |
1 2 3 4 5 6 | class compilehang { public static void main(String[] args) { double d = 2.2250738585072012e-308; System.out.println("Value: " + d); } } |
Source : Exploring Binary
Et vous ?
-
YannPeniguelMembre éprouvé
Toute personne malveillante connaissant ce bug et souhaitant dégommer ton application par un moyen, exposé publiquement, de lui fournir cette valeur en entrée. Mettons par exemple dans les appels AJAX utilisant des JSP, ou dans les parametres d'url pour tes servlets Java...le 08/02/2011 à 17:20 -
CrydeMembre du ClubComme quoi, les détracteurs du PHP auront vite compris qu'il n'y a pas que ce langage qui posait problème avec ça ^^le 08/02/2011 à 18:56
-
Rom_1Membre régulierUne attaque par déni de service est une attaque visant à rendre un service inutilisable.
Si ca marche avec une seule requête, l'attaque n'en est que plus efficace.
Mais normalement, le serveur web devrait utiliser un thread par requête (donc une requête ne bloque au maximum qu'un cœur et pas le service entier) et tuer le thread après un certain temps d'exécution.
Enfin c'est quand même sacrément efficace.
EDIT : vu les explications de la personne qui a découvert le bug, le problème vient du fait que la FPU des processeurs x86 utilise une précision étendue (80 bits) dans tous les cas, et ne sait pas calculer en double précision (64 bits). Donc ca viendrait plus de la plate-forme que du langage.
Et donc, ce ne serait pas étonnant que d'autres langages soient touchés, par exemple .net ou python...le 13/02/2011 à 10:43 -
stealth35Expert éminent séniorle 08/02/2011 à 15:54
-
Derek CorganMembre chevronnéEffectivement, Eclipse plante lamentablement à l'exécution (Eclipse 3.4, JKD1.6_20 + Windows XP).
Avant, la probabilité de survenance de ce bug était quasi nulle.
Maintenant que cela est connu il risque d'apparaitre dans des flux de données, soit pour faire une petite blague à un collègueou pour faire chier le 08/02/2011 à 18:18 -
nidgetMembre du ClubJe confirme ce bug sur JDK 1.6.0_20le 09/02/2011 à 7:13
-
YannPeniguelMembre éprouvéLa question n'est pas que ce soit bloquant en terme d'usage, mais que cela permette de provoquer le plantage d'une application, potentiellement une application JEE qui impactera des milliers d'utilisateurs (ERP, CRM...)le 10/02/2011 à 14:18
-
LorantusMembre éclairéCe patch est interssant, car il est en Java. Un peu de rétro-engenering pour voir "comment cela se passe".
Je sais, c'est pas bien
le 10/02/2011 à 17:35 -
igor24Membre régulierEclipse a planté rien qu'en collant le 2nd bout de code ..., normal il compile à la voléele 08/02/2011 à 16:06
-
ztor1Membre avertiQuestion idiote ?
Je peux ?
Qui utilise un chiffre pareil ? 2.2250738585072011e-308
Cela me fait penser au bug du pentium I à sa sortie.
Les exemples cités java ou php ... On utilise vraiment cela ?le 08/02/2011 à 16:11