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
|