[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#581240: [gdc-4.3] Calculation of MD5 sums seriously broken



On 11 May 2010 23:03, Daniel Gibson <metalcaedes@gmail.com> wrote:
Package: gdc-4.3
Version: 1:1.046-4.3.4-5
Severity: serious


The MD5-sums calculated by std.md5 are seriously broken - they're not
only wrong, they're different on each run..
gdc-4.1 and the closed-source dmd do *not* have this bug. Because
md5.d in the gdc-4.1 and gdc-4.3 package sources are identical I file
this as a bug in the compiler, not libphobos.
I consider this a serious bug because it makes std.md5 unusable and
probably affects other code as well (why should it only break the MD5
code).

I attached a simple testcase to demonstrate this bug. When it's build
with gdc-4.1 I get the following output:
"900150983CD24FB0D6963F7D28E17F72", when it's built with gdc-4.3 I
get:
"9BB8D85B9EC69BAAE48AFD6DC642C4B7
Error: AssertError Failure md5test.d(8)"
or "73295B9A9D13003D9E6065260759FBD4
Error: AssertError Failure md5test.d(8)"
... (a different sum on each run).

Cheers,
- Daniel



Thank-you for your report, this seems to be a problem with gdc's inline asm.

Attached is the minimal code to reproduce, however, it seems that I can get it in even less.

asm
{
   naked ;
   mov EAX x ;
   ret ;
}

Haven't looked into it properly yet, but conjures the thought of data not being initialised properly.


First advancements though, turning off asm in std.md5 seems like a likely quick-fix for the time being. Just comparing, GCC can produce the rol opcode from shifts. Actually, produces _exactly_ the same code as the inline assembly in the D file (with the exception of a different call frame setup). So is not likely we are loosing any optimisation either way.

I'd hate to think where else in phobos is affected by this... 


Regards

--
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
import std.stdio;

uint test_asm(uint x, uint n)
{
    asm
    {
	naked ;
/+	mov ECX, n ; +/
	mov EAX, x ;
/+	rol EAX, CL ; +/
	ret ;	/+ Returns 42 in gdc-4.1.
	    	A Random number is returned in gdc-4.3 +/
    }
}

void main()
{
    writefln( test_asm(42, 1) );
}


Reply to: