Vous avez peut-être suivi l’histoire au début de l’année concernant un bug critique sur PHP qui permettait de faire planter complètement des serveurs simplement en passant un nombre particulier à un code PHP. Et bien il semblerait que ce ne soit pas mieux côté Java, puisque l’on vient d’apprendre que le même genre de bug fait planter Java à la compilation ainsi qu’à l’exécution

Pour PHP, le bug était relativement simple : il consistait à faire entrer PHP dans une boucle infinie en le poussant à convertir un nombre à virgule flottante et à précision double d’une taille importante (en fait le plus grand) : 2.2250738585072011e-308.

Le problème n’affectait que les binaires de PHP en 32 bits. Pour voir si vous êtes vulnérables, vous pouvez d’ailleurs tester ce code PHP :

<?php
/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2011 The PHP Group                                     |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Johannes Schlueter <johannes@php.net>                        |
  +----------------------------------------------------------------------+
*/
 
if (PHP_SAPI != 'cli') {
    die("Please run this test from CLI!\n");
}
 
ini_set('display_errors', 1);
ini_set('output_buffering', 0);
error_reporting(-1);
if (!ini_get('safe_mode')) {
    set_time_limit(1);
}
 
echo "Testing float behaviour. If this script hangs or terminates with an error ".
     "message due to maximum execution time limit being reached, you should ".
     "update your PHP installation asap!\n";
echo "For more information refer to <http://bugs.php.net/53632>.\n";
$d = (double)"2.2250738585072011e-308";
echo "Your system seems to be safe.\n";
?>

Si le script affiche la dernière ligne, c’est cool, sinon il partira dans une boucle infinie et vous n’en verrez jamais la fin.

Et Java dans tout ça ?

Tout le monde critiquait PHP lors de la découverte du bug, mais finalement ce n’est pas mieux pour les autres puisqu’on vient d’apprendre que Java plante en convertissant le nombre 2.2250738585072012e-308.

Et le pire pour Oracle et Sun, c’est que le bug a été signalé en… 2009 mais aussi en….2001!
Dix ans plus tard le bug n’est toujours pas corrigé.

Plus drôle, le rapport de bug de 2009 est bien disponible, par contre celui de 2001 qui fait mauvais effet a été supprimé…dans la journée d’hier. Heureusement le cache de Google fait des merveilles et l’on voit bien que le nombre 2.225073858507201E-308 est cité.

Du coup, comme le signale un commentaire sur la source originale, il est possible de faire planter des serveurs Tomcat de manière assez simple avec une commande du type :

curl -H "Accept-Language: en-us;q=2.2250738585072012e-308" http://adresse

Si le serveur appelle la fonction getLocale() sur cette requête, cela provoquera un plantage du thread. Les correctifs ont été apportés à Tomcat il y a deux jours, pas sûr que les serveurs sur le Web soient déjà patchés…

Bien sûr, l’équipe d’Oracle travaille ardemment sur le sujet. Nous voilà rassurés ;)

 


 

8 réponses pour "Le nombre magique qui fait planter Java : 2.2250738585072012e-308"

  1. Olivier  Surfe sur Google Chrome Google Chrome 9.0.597.86 avec Windows Windows 7
    04 février 2011 @ 14:09
    1

    Ce bug n’est pas spécifique à un language apparement, « il trouve en effet son origine au sein de l’unité de calcul en virgule flottante x87 des processeurs x86 32 bits ». Plus d’info ici : http://blog.mageekbox.net/?post/2011/02/01/%C3%80-propos-du-bug-53632-de-PHP

  2. th3m4ri0  Surfe sur Android Browser Android Browser avec Android Android 2.3.2
    04 février 2011 @ 14:18
    2

    Oracle : faire de l’argent d’abord, réfléchir après.

  3. Mike  Surfe sur Mozilla Firefox Mozilla Firefox 3.6.13 avec Ubuntu Linux Ubuntu Linux
    04 février 2011 @ 15:38
    3

    Il faut remplacer  » par ‘ pour lancer curl ;-)

  4. boa13  Surfe sur Mozilla Firefox Mozilla Firefox 3.6.13 avec Windows Windows XP
    04 février 2011 @ 17:44
    4

    Olivier : les deux bugs n’ont pas du tout la même cause technique (et ce ne sont d’ailleurs pas les mêmes nombres). Le point commun est que ce sont des nombres « limite », des cas tordus et difficiles à gérer (ce qui n’est pas une excuse bien sûr).

    th3m4ri0 : ce bug a près de 10 ans, ça n’a rien à voir avec Oracle (sauf qu’ils mettent du temps à publier une version corrigée !).

    Papy Geek : le nombre est en effet cité dans le rapport de bogue de 2001, mais pas en tant que chaîne de caractères qui fait planter. Et clairement, ce bogue avait jusqu’à présent été considéré comme un problème de math, pas comme un problème de sécurité (pas une excuse non plus).

  5. sac à main  Surfe sur Google Chrome Google Chrome 5.0.375.127 avec Windows Windows Vista
    04 février 2011 @ 17:54
    5

    aiie aie bonjour les degats !

  6. Geronimo  Surfe sur iOS iOS 4.2.1
    04 février 2011 @ 19:58
    6

    Rendons a César ce qui lui appartient: en 2001, sun était le détenteur de java… Et donc du bug.

  7. Soso  Surfe sur Mozilla Firefox Mozilla Firefox 3.6.13 avec Windows Windows 7
    08 février 2011 @ 15:10
    7

    En effet, le bug est parfaitement reproductible à l’aide de ce bout de code :

    public static void main(String[] args) {

    System.out.println(« Début »);

    double d = Double.parseDouble(« 2.2250738585072012e-308 »);

    System.out.println(« Jamais affiché :  » + d);

    }

    Plus de détails ici : http://java.developpez.com/actu/28335/Le-bogue-des-nombres-a-virgule-flottante-refait-surface-en-Java-il-plonge-le-compilateur-et-les-programmes-dans-des-boucles-infinies/

  8. boa13  Surfe sur Mozilla Firefox Mozilla Firefox 3.6.13 avec Windows Windows XP
    09 février 2011 @ 5:06
    8

    Tomcat 5.5.33 (pas encore publié), 6.0.32, et 7.0.7 contiennent le correctif pour la mauvaise gestion de l’en-tête Accept-Language.

    Java 1.6.0_24 (pas encore publié, probablement dans une semaine) contiendra le correctif pour la boucle infinie causée par le nombre magique.

    En attendant, pour ceux qui ont du Java en prod et qui doivent le patcher sans attendre la nouvelle version de Java (ou sans pouvoir changer de version), Oracle a publié un outil qui corrige le rt.jar (qui contient la classe fautive) :

    http://www.oracle.com/technetwork/java/javase/fpupdater-tool-readme-305936.html

    Et ça fait joli le gros « Security Alert » sur la page de téléchargement J2SE, non ? :-)

    http://www.oracle.com/technetwork/java/javase/downloads/index.html

À en croire le fact #4688, mieux vaut se diriger vers le sud. +