Door Jolt Oops op zondag 12 februari 2006 00:11
> Dit is (in mijn ogen) onverwacht gedrag omdat ik
> zou verwachten dat de (signed) integer 'i'
> gepromote wordt naar een unsigned int
gepromote? Je bedoelt dat 0xFFFFFFFF in het geheugen
ineens niet als -1 maar als +4294967295 zou moeten worden
gelezen, en dat dan
wel verwacht gedrag en geen
(security) fouten zou opleveren?
Wel hebben alert7 (de FD poster) en jij gelijk dat Borland
zich niet aan haar eigen handleiding houdt. Je hebt echter
geen IDA nodig, gewoon een breakpoint zetten en een CPU
window openen werkt ook:
Unit1.cpp.9: int i = -1;
0040116C C745FCFFFFFFFF mov [ebp-0x04],0xffffffff
Unit1.cpp.10: if(i < sizeof(int)) printf("tsja!n);
00401173 837DFC04 cmp dword ptr [ebp-0x04],0x04
00401177 7D0B jnl +0x0b
00401179 68A4204000 push 0x004020a4
0040117E E87D010000 call CC3260._printf
dus een signed conditional jump (die niet genomen wordt
omdat -1 kleiner is dan 4).
Uit de online manual:
The fundamental types
...
Standard arithmetic conversions
When you use an arithmetic expression, such as a + b, where
a and b are different arithmetic types, C++Builder performs
certain internal conversions before the expression is
evaluated. These standard conversions include promotions of
"lower" types to "higher" types in the interests of accuracy
and consistency.
...
7. Otherwise, if either operand is of type unsigned, then
the other operand is converted to unsigned.
Vertrouwen op een dergelijke conversie is m.i. fundamenteel
fout (maakt niet uit welke kant op), doodeenvoudig omdat er
slechts voor de helft van alle mogelijke getallen een
overlap is tussen beide types; unsigned is dus helemaal geen
"higher" type dan signed. Normaal gesproken levert dit dan
ook een warning op: "W8012 Comparing signed and unsigned
values" (maar van mij had dit een foutmelding mogen zijn).
Het grootste probleem van deze compiler bug ("vergeten" dat
sizeof() unsigned teruggeeft) is m.i.
niet het op
onverwachte wijze evalueren van de expressie, maar het feit
dat de programmeur er niet d.m.v. een warning op gewezen
wordt dat hij een fout gemaakt heeft.
De kans op security fouten door deze compiler bug is denk ik
klein; sizeof wordt meestal gebruikt om de grootte van
structs te bepalen en daarbij zal het meestal om unsigned
vergelijkingen gaan.
> Maar het punt is dat je een ultra-secure-evil-hacker-
> proof stuk C gecode kan hebben maar nog steeds
> 'onveilig' kan zijn als je compiler of interpreter 'lek' is.
Ja, maar ik maak me meer zorgen over libraries.
Erik van Straten