Visar inlägg med etikett subnormala tal. Visa alla inlägg
Visar inlägg med etikett subnormala tal. Visa alla inlägg

onsdag 5 januari 2011

DoS:a PHP med en siffra

Flyttalet 2.2250738585072011e-308 hänger PHP 5.3 och öppnar upp för enkla men effektiva DoS-attacker.

Varför? Läs vidare.

Normala flyttal
Ett 64-bitars flyttal representeras av en teckenbit, elva exponentbitar och 52 mantissabitar. Elva bitar till exponenten innebär att minsta tillåtna exponent är -1022 och den maximala är 1023.

Ett så kallat normalt flyttal karaktäriseras också av att första siffran i mantissan är skild från noll, t ex 6.008043e10. Om första siffran vore noll, t ex 0.540030002e13 så skulle ju talet kunna skrivas 5.40030002e12, dvs med femman först, tolv som exponent och man hade tjänat en siffras precision i mantissan. Därför har man också kunna tolka den första biten som implicit eller gömd. Alltså har man 53 bitars precision i mantissan.

Det betyder att det minsta normala, 64-bitars flyttalet är binärt 1e-1022, decimalt 2.2250738585072010e-308.

Subnormala tal
Vad händer om datorn får ett resultat som är mindre än 1e-1022? Tidigare så ledde det till "flush to zero", dvs resultatet blev noll. Men sen kom man på att till priset av förlorad precision (= mindre antal signifikanta siffror i mantissan) så kunde man fortfarande representera resultatet som ett flyttal. Tricket var att låta första biten i mantissan vara noll för dessa subnormala tal! Exponenten representeras av bara nollor.

Nu plötsligt kunde man representera tal som 0.0000000010111e-1022.

Subnormala tal och PHP
Låt oss nu titta på det där talet som hängde PHP 5.3.

2.2250738585072011e-308 = 0.1111111111111111111111111111111111111111111111111111 x 2^-1022

I minnet representeras det av:
Teckenbiten: 0
Exponenten: 00000000000
Mantissan: 1111111111111111111111111111111111111111111111111111

Om ni räknar ettorna så ser ni att de är 52 till antalet. Tillsammans med den inledande nollan (implicit för 0-exponent) så fyller de hela mantissan på 53 bitar. Vi har alltså att göra med det största möjliga, subnormala flyttalet i ett 64-bitarssystem.

Och det värdet hänger tydligen PHP 5.3!