Win Tims Money! a.k.a. find my sockets bug!

Duane Maxwell dmaxwell at entrypoint.com
Fri Apr 21 23:32:07 UTC 2000


I'm pretty sure it went like this:

The IP address was the four bytes:

D0 DA 03 01 (208.218.3.1)

But as signed 32-bit values, they are:

FFFFFFD0 FFFFFFDA 00000003 00000001

After shifting each byte by the appropriate bits, we then added:

D0000000
FFDA0000
00000300
00000001

which gives us:

CFDA0301

which is what John discovered

>Duane Maxwell wrote:
>>
>> Tim -
>>
>> So how is this going to work?
>>
>> Are you paying John and then I'm paying you?
>>
>> Note to lurkers - this is a _really_ interesting bug, and it's a wonder it
>> hasn't popped up before.  It seems to happen due to addition of sign
>> extended numbers.  This big clue in John's IP example is that the high byte
>> ended getting  reduced by one - or alternatively had 16rFF added to it -
>> which is what happens if the byte below gets sign extended...
>
>But how? I want to give an example for different results depending on
>casting.
>
>Addition of two bytes
>
>decimal			byte
>(signed char)     -1    1111 1111
>(unsigned char)  127    1111 1111
>.
>
>So
>
>-> (signed char)    -1  +  (unsigned char) 127
>-> (signed int)     -1  +  (signed int)    127
>-> (signed int)	   126
>-> (unsigned char) 126
>
>, but if the first operand is casted to from signed to unsigned for
>whatever reason, then
>
>-> (unsigned char) ((signed char) -1) +  (unsigned char) 127
>-> (unsigned char)               127  +  (unsigned char) 127
>-> (signed int)                  127  +  (signed int)    127
>-> (signed int)    254
>-> (unsigned char) 254
>
>the result is different.
>The intermediate step by computing with ints is so defined for the
>C-language (integral promotion).
>
>
>Was this the problem? Or was it more tricky?
>
>
>Greetings,
>
>Stephan
>
>>
>> How does this happen?  Well, it appears than with some compilers,
>> ObjectMemory>>fetchByte:ofObject: will return a sign-extended char.  I
>> would hypothesize that this is not the intended behavior.
>>
>> So, I think the actual fix is:
>>
>> ObjectMemory>>fetchByte: byteIndex ofObject: oop
>>
>>  ^ self byteAt: (self cCoerce: oop to: 'unsigned char *') + BaseHeaderSize
>> + byteIndex
>>
>> >In message <200004212016.PAA09260 at dcs-server1.cs.uiuc.edu> you wrote:
>> >
>> >> Ok, found it I'll only claim a $1.00 since I've not posted the solution
>> >> however in the code given this problem:
>> >>
>> >> D0DA0301 is the byte array for www.disney.com  (208.218.3.1)
>> >>
>> >> when you invoke
>> >> addr = netAddressToInt(address);
>> >>
>> >> then addr gets
>> >> CFDA0301  which of course is 207.218.3.1
>> >>
>> >> The problem lurks in netAddressToInt when it grabs bytes and shifts then
>> >> adds them I think some compilers think and do signed math?
>> >
>> >Yup, that's it. Hacking the generated C to use unsigned char* instead of
>> >char * makes it work. I'll clean up the slang later after a drunken orgy
>> >of celebration. Thank you John, you get the prize, the adulation, the
>> >girls/boys/goats (delete as appropriate).
>> >
>> >Oh, the joy of C. :-(
>> >
>> >tim
>> >--
>> >Tim Rowledge, tim at sumeru.stanford.edu, http://sumeru.stanford.edu/tim
>> >To be, or not to be, those are the parameters.
>
>--
>Stephan Rudlof (sr at evolgo.de)
>   "Genius doesn't work on an assembly line basis.
>    You can't simply say, 'Today I will be brilliant.'"
>    -- Kirk, "The Ultimate Computer", stardate 4731.3







More information about the Squeak-dev mailing list