The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

DoS-уязвимость при обработке некоторых чисел с плавающей запятой

05.01.2011 23:02

В интерпретаторе PHP версий 5.2 и 5.3 была обнаружена довольно странная ошибка: при обработке некоторых числовых значений (в частности, 2.2250738585072011e-308) интерпретатор зависал (достаточно выполнить "$a = 2.2250738585072011e-308;" или "$a = '2.2250738585072011e-308'; echo $a + 0;").

Как показали дальнейшие исследования, такое поведение интерпретатора вызвано наличием ошибки округления, порождающей бесконечный цикл при попытке преобразования строки в число. Что характерно, сходные аномалии при операциях с вещественными значениями были замечены при работе с gcc еще в 2000 году. Однако, стоит подчеркнуть, что корень ошибки кроется не в конкретной реализации компилятора, а в некорректной работе процессоров архитектуры x86 с вещественными 64-битными типами данных, при задействовании набора инструкций x87. На других архитектурах, включая x86_64, данная ошибка не возникает (в x86_64 вместо x87 используются инструкции SSE2).

Возникшая в результате этой ошибки DoS-уязвимость PHP может быть задействована удаленно — достаточно передать «магическое число» в качестве значения параметра, с которым в коде производятся какие-либо арифметические операции (в виде обычной стоки такое число, естественно, угрозы не представляет — проблема возникает при преобразовании этой строки в число). Кроме числа 2.2250738585072011e-308, подобный эффект вызывают числа 0.22250738585072011e-307, 22.250738585072011e-309 и 22250738585072011e-324.

Как уже упоминалось, данной проблеме подвержены ветки PHP 5.2 и 5.3. В готовящейся к выходу версии 5.3.5 она уже исправлена, для остальных версий можно задействовать простой патч (добавляет спецификатор volatile перед некоторыми объявлениями типа double). Другим вариантом решения проблемы является пересборка PHP с опцией "-ffloat-store" или "-mfpmath=sse".

Дополнение: доступен для загрузки релиз PHP 5.3.5 с устранением уязвимости.

  1. Главная ссылка к новости (http://www.theregister.co.uk/2...)
  2. PHP Hangs On Numeric Value 2.2250738585072011e-308
  3. GCC bug #323
  4. The pitfalls of verifying floating-point computations
Автор новости: Sergey Ptashnick
Лицензия: CC BY 3.0
Короткая ссылка: https://opennet.ru/29203-php
Ключевые слова: php, security
При перепечатке указание ссылки на opennet.ru обязательно


Обсуждение (38) Ajax | 1 уровень | Линейный | +/- | Раскрыть всё | RSS
  • 1.6, б.б. (?), 02:11, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Чего бы такого поломать...

    Кстати, что-то я не понял, обычно же процессы php рождаются и умирают, и что даст смерть процесса?

     
     
  • 2.7, б.б. (?), 02:15, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Сейчас проверил на lighttpd+cgi и apache+mod_php5, в обоих случаях только выполнение скрипта зависало, а сам сервер как работал, так и продолжает работать, как и раньше.
     
  • 2.11, Sylvia (ok), 02:24, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +1 +/
    > Кстати, что-то я не понял, обычно же процессы php рождаются и умирают,
    > и что даст смерть процесса?

    представьте себе что подобную ситуацию генерирует внешний злоумышленник,
    много раз, в это время php будет кушать процессор, пока не умрет по max_execution_time

    бесполезный расход ресурсов вообщем, если сервер с маленькими ресурсами, то ему несколько таких запросов одновременно может и хватить чтобы он перестал обслуживать остальных

     
     
  • 3.27, Петя Васечкин (?), 13:23, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • –3 +/
    >> Кстати, что-то я не понял, обычно же процессы php рождаются и умирают,
    >> и что даст смерть процесса?
    > представьте себе что подобную ситуацию генерирует внешний злоумышленник,

    И как же ему это сделать интересно :) ?
    Чтобы какую-то "вредоносную строку" обработал движок PHP целевой системы - нужно сначала залить на целевую систему файл dos.php (что просто так тоже не сделать) и потом уже движком сайта попытаться его открыть ?
    типа http://target.ru/dos.php ? или можно через адресную строку браузера передать "вредоносную строку" ?


     
     
  • 4.33, 310dej (?), 19:01, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    <?php
      if($_GET("A")) $a=doubleval($_GET(A));
    ?>

    На форумах и блогах такое увидишь не часто... Но на сайтах других типов (а-ля office online).

     
  • 4.39, Аноним (-), 06:38, 07/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > И как же ему это сделать интересно :) ?
    > Чтобы какую-то "вредоносную строку" обработал движок PHP целевой системы - нужно сначала
    > залить на целевую систему файл dos.php (что просто так тоже не
    > сделать) и потом уже движком сайта попытаться его открыть ?
    > типа http://target.ru/dos.php ? или можно через адресную строку браузера передать "вредоносную
    > строку" ?

    какой наивный...

     

  • 1.8, Sylvia (ok), 02:15, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    а -mfpmath=sse никак они комментируют на x86 ? по сути получается то же, что и на amd64
     
     
  • 2.10, Sylvia (ok), 02:19, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    <?php
    $a = '2.2250738585072011e-308';
    echo $a + 0;
    ?>
    проверила у себя на сервере, ничего не зависло, php 5.3.4 собрана с -march=core2 -mfpmath=sse -mssse3
     
     
  • 3.12, filosofem (ok), 03:07, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    аналогично
    filosofem@ivan-01:~$ php -a
    Interactive shell

    php > $a = 2.2250738585072011e-308;
    php > echo $a + 0;
    2.2250738585072E-308
    php > ^Dfilosofem@ivan-01:~$ php -v
    PHP 5.3.3-1ubuntu9.1 with Suhosin-Patch (cli) (built: Oct 15 2010 14:00:18)
    Copyright (c) 1997-2009 The PHP Group
    Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

    Нужна статистика какие версии и как запущены. Уязвимы я полагаю конкретно какие-то версии  модуля апача.

     
     
  • 4.13, Sylvia (ok), 03:11, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    по версиям как раз написано, что уязвимы все 5.2 и 5.3, втч и 5.3.4
    в вашем случае интересно влияние сухосина на уязвимость )

     
     
  • 5.14, filosofem (ok), 03:13, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > по версиям как раз написано, что уязвимы все 5.2 и 5.3, втч
    > и 5.3.4
    > в вашем случае интересно влияние сухосина на уязвимость )

    Еще интересно влияние как запущен PHP, как модуль, или как CGI.

     
     
  • 6.15, Sylvia (ok), 03:19, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Zend/zend_strtod.c

    патч на этот файл, zend engine собирается одинаково в любом случае, что cli, что cgi, что mod_php , что php-fpm , на сервере проверила с php-fpm, дома с 5.3.4 cli (Gentoo)
    и там и там -mfpmath=sse , так что FPU x87 для проявления ошибки не задействован,

    а вот в убунте собирают с -mfpmath=387, да и в остальных бинарных дистрах для x86 тоже, включая и archlinux , так что там по идее должно бы и проявляться зависание интерпретатора , причем способ вызова должен быть не важен, т.к. это в ZendEngine

     
     
  • 7.17, filosofem (ok), 03:36, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Да, как модуль тоже не работает. И PHP 5.2.6-1+lenny9 тоже один хрен ничего не виснет, хотя округлил иначе.

    brutal@debian-printer1:~$ php -r "\$a = 2.2250738585072011e-308;echo \$a + 0;"
    2.22507385851E-308brutal@debian-printer1:~$ php -v
    PHP 5.2.6-1+lenny9 with Suhosin-Patch 0.9.6.2 (cli) (built: Aug  4 2010 03:25:57)
    Copyright (c) 1997-2008 The PHP Group
    Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
    brutal@debian-printer1:~$

    Может и сухосин.

    ЗЫ Попробовал почитать обсуждение, там какой-то матан. =) Ну его, не работает и хорошо.

     
     
  • 8.18, б.б. (?), 04:24, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Да, действительно, на Lenny не зависает А на squeeze и sid при запуске через cl... текст свёрнут, показать
     
  • 7.24, Sw00p aka Jerom (?), 12:01, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Zend zend_float h Copy of the contents of xpfpa h which is under public doma... большой текст свёрнут, показать
     
  • 7.26, Sw00p aka Jerom (?), 12:13, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    а патч радует ))

    - double aadj, aadj1, adj;
    + volatile double aadj, aadj1, adj;

    XDDDDDDDDDDD

     
  • 5.42, RedRat (ok), 19:57, 09/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    На x86 FreeBSD-6 + PHP 5.3.4 + Suhosin баг воспроизводится, так что сухосин тут не панацея. :-/
     
  • 3.21, К.О. (?), 11:23, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    PHP 5.2.16. Проверил в CLI и модулем апача - ничего не виснет. x86_64, сборка с -march=amdfam10
     
     
  • 4.23, Sw00p aka Jerom (?), 11:54, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    написанно же

    (в x86_64 вместо x87 используются инструкции SSE2)

    а вот у мня тож не зависает - x86

    # php -r "\$a = '2.2250738585072011e-308';echo \$a + 0;"
    # 2.2250738585072E-308

    # php -v
    PHP 5.2.6 (cli) (built: Oct 11 2008 01:21:44)
    Copyright (c) 1997-2008 The PHP Group
    Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
        with Zend Extension Manager v1.2.2, Copyright (c) 2003-2007, by Zend Technologies
        with Zend Optimizer v3.3.7, Copyright (c) 1998-2007, by Zend Technologies

    # cat /proc/cpuinfo
    processor       : 0
    vendor_id       : GenuineIntel
    cpu family      : 6
    model           : 13
    model name      : Intel(R) Pentium(R) M processor 1.70GHz
    stepping        : 6
    cpu MHz         : 600.000
    cache size      : 2048 KB
    fdiv_bug        : no
    hlt_bug         : no
    f00f_bug        : no
    coma_bug        : no
    fpu             : yes
    fpu_exception   : yes
    cpuid level     : 2
    wp              : yes
    flags           : fpu vme de pse tsc msr mce cx8 mtrr pge mca cmov pat clflush dts acpi mmx fxsr sse sse2 ss tm pbe up est tm2
    bogomips        : 1196.84

     
  • 3.38, php532 (?), 03:33, 07/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    у меня зависло php 5.3.2
     
  • 2.16, R (?), 03:29, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Да, пишут, что -mfpmath=sse спасает
    http://www.reddit.com/r/programming/comments/evtrq/php_hangs_on_numeric_value
     
     
  • 3.25, Sw00p aka Jerom (?), 12:07, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Implementation notes:

    x86_64:
      - Since all x86_64 compilers use SSE by default, it is probably unecessary
        to use these macros there.

     

  • 1.9, Аноним (-), 02:18, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Факт, у меня одно ядро на 100% занимается
     
  • 1.19, б.б. (?), 09:34, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Вот, выглянуло солнышко, и в debian sid прилетел пакетик php 5.3.3-7

    php -r "\$a = 2.2250738585072011e-308;echo \$a + 0;"
    2.2250738585072E-308

    интересно, когда это в squeeze попадёт?

     
  • 1.20, pro100master (ok), 11:01, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    еще дохнут сайты с "левыми реализациями" json, которая (самая распространенная) содержит floatval().

    Кстати, дохнет не только пхп, а судя по всему, вся нить в ядре. Ядро, правда, после снятия процесса, отмирает :)

     
     
  • 2.22, К.О. (?), 11:24, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > еще дохнут сайты с "левыми реализациями" json, которая (самая распространенная) содержит
    > floatval().
    > Кстати, дохнет не только пхп, а судя по всему, вся нить в
    > ядре. Ядро, правда, после снятия процесса, отмирает :)

    BSD? xD

     
     
  • 3.43, RedRat (ok), 20:01, 09/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    На FreeBSD-6 завис только PHP-процесс (жрал проц на 100%), но вся остальная система работала нормально.
     

  • 1.28, q11q11 (?), 13:39, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • –1 +/
    бубунта 9.04, xampp 1.7.1 ( Apache 2.2.11, php 5.2.9 )
    <?php
    $a = '2.2250738585072011e-308';
    echo $a + 0;
    ?>
    сразу выдало
    2.22507385851E-308

    ничего не зависло

     
     
  • 2.30, gabin (ok), 16:36, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • –1 +/
    потому что обработало как строку , а не как float число
     
     
  • 3.41, q11q11 (?), 00:49, 08/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    ну да, но только при
    <?php
    $a = '2.2250738585072011e-308';
    echo $a + 1;
    ?>
    выдавало "1"
    а при
    <?php
    $a = '2.2250738585072011e-308';
    echo $a - 1;
    ?>
    выдавало "-1"

    то можно предположить что вычисление прошло успешно и зависания не было

     

  • 1.29, R (?), 16:36, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    This vulnerability is present on all versions of PHP including PHP 4.x and 5.x, on all Intel-based 32-bit PHP builds.

    Platform Vulnerable
    Windows YES
    Linux (using 32-bit PHP build) YES
    Linux (using 64-bit PHP build) NO
    Mac OS NO
    IBM i NO

    http://www.zend.com/en/community/php/php-remote-exploit

    Можно новость чутка обновить :))

     
     
  • 2.31, pavlinux (ok), 16:50, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > Mac OS NO

    Макоси не работают на 32-битных процах.  
    > IBM i NO

    Очень интересует наличие уязвимости на Plan9 под Alpha 21384 :)

     
     
  • 3.32, R (?), 17:04, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    главное тут
    >all versions of PHP including PHP 4.x and 5.x

    )

     

  • 1.34, pavlinux (ok), 19:19, 06/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Чой-то мене число "e-302" напоминает, так называемую  "эпсилон" - машинный нуль, у любого процессора.





    #include <stdio.h>

    int main(void) {

            int k;
            long double e, a;

            e = 1.0F;
            k = 0;

            do {
                    e /= 2.0F;
                    a = e + 1.0F;
                    k++;

            } while ( a > 1.0F );

            printf("\nЧисло делений на 2: %6d\n", k);
            printf("Машинный нуль: %e\n", e);

      return 0;
    }


    Число делений на 2:     64
    Машинный нуль: 4.940656e-324

    Почти похоже :)

     
     
  • 2.35, R (?), 20:04, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Надо ссылки читать просто:
    >What’s Special About 2.2250738585072011e-308?
    >2.2250738585072011e-308 represents the largest subnormal double-precision floating-point number; written as a hexadecimal floating-point constant, it’s 0x0.fffffffffffffp-1022. 2.2250738585072011e-308 is one of five 17-digit decimal values that convert (correctly) to 0x0.fffffffffffffp-1022:

    2.2250738585072007e-308
    2.2250738585072008e-308
    2.2250738585072009e-308
    2.2250738585072010e-308
    2.2250738585072011e-308

    http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e

     
     
  • 3.36, pavlinux (ok), 20:59, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > Only 2.2250738585072011e-308 causes the problem.

    Может 2011 связано как-то с текущим годом? :)

    У кого есть PHP на 32-битах, переведите часы на месяц назад и

    <?php
          $a = '2.2250738585072010e-308';
          echo $a + 0;
    ?>

    %-)

     
     
  • 4.37, ram_scan (?), 23:07, 06/01/2011 [^] [^^] [^^^] [ответить]  
  • +1 +/
    А чо часы то переводить ? Этой баге концептуально минимум лет 30, на моей памяти впервые она на спектруме еще в калькуляторе в 1982 году вылезла, и заключается она в неоднозначности машинного представления нуля с плавающей точкой. Тогда тоже округление от 65535 равнялось -1. То есть плюха вокруг разницы и одинаковости машинного преставления чисел +0, 0 и -0.

    Теоретически плюха эта будет работать не только в похапе, а вообще в любой программе которая скомпилена с поддержкой FP x87, ибо плюха эта сидит в самом x87 сопроцессоре. Просто в похапе ей технически как два пальца воспользоваться.

     

  • 1.40, R (?), 11:45, 07/01/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    PHP 5.3.5 and 5.2.17 Released!

    [06-Jan-2011]
    The PHP development team would like to announce the immediate availability of PHP 5.3.5 and 5.2.17.

    This release resolves a critical issue, reported as PHP bug #53632, where conversions from string to double might cause the PHP interpreter to hang on systems using x87 FPU registers.

    The problem is known to only affect x86 32-bit PHP processes, regardless of whether the system hosting PHP is 32-bit or 64-bit. You can test whether your system is affected by running this script from the command line.

    All users of PHP are strongly advised to update to these versions immediately.

    http://www.php.net/archive/2011.php#id2011-01-06-1

     

     Добавить комментарий
    Имя:
    E-Mail:
    Текст:



    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру