md5sum makes unaligned word accesses...

Rob Landley rob at landley.net
Mon May 15 23:37:14 UTC 2006


On Monday 15 May 2006 5:35 pm, Andre wrote:
> Rob Landley <rob at landley.net> wrote:
> > I just changed my copy of md5_hash() to look like:
> >
> > void md5_hash(const void *data, size_t length, md5_ctx_t *ctx)
> > {
> >     /* We can only call the hash function directly on data that's
> >      * 32-bit aligned and a multiple of 64 bytes. */
> >
> >     if ((length&63) || (data&3)) md5_hash_bytes(data, length, ctx);
> >     else md5_hash_block(data, length, ctx);
> > }
>
> Did you miss my message about the current md5_hash(),
> md5_hash_bytes(), md5_hash_block() API being broken regardless to
> alignment issues ??

Apparently I did, but I planned on running it against both a large file and a 
tree of smaller files and comparing the output with ubuntu's md5 command 
before checking it in.

> The following fails on all platforms, including x86...
>
> # echo -n "1234" > 4bytes
> # echo -n "abcdefghijklmnopabcdefghijklmnop" > 32bytes
> # cat 32bytes 32bytes > 64bytes
> #
> # ( cat 4bytes; sleep 1; cat 64bytes ) | md5sum
>
> Correct answer: 0314c5f1e2d1f87b9481e3a2e08ab452
> Busybox answer: 12076da5776df62e0c913dd3dad5d032

Still, a specific test we fail is always good. :)

> Please consider applying the attached patch before any alignment
> fixes.

Hmmm...  Force all access through the buffering function?  Ah, I see.  Small 
chunks of data followed by large aligned chunks of data can get out of 
sequence because one's bypassing the buffer and the other's not.

Good catch.

From a performance standpoint having one codepath is actually a bonus.  The 
memory allocation for the buffer always happens anyway, and from a 
performance standpoint the small buffer is cache-local and cache hot when 
it's processed.  It's more or less doing a DRAM prefetch, really.

(I'm dreadfully tempted to clean up the tangled #ifdefs for the various 
performance levels, but I'm resisting mightily.  If nothing else, that can be 
a second pass after this is working and checked in...)

> Andre

Hmmm...  Running md5sum on a large tree, I'm getting a segfault and it's not 
in the code I just changed...  Oh good grief.  You know all the big 
"performance range" stuff for libbb/md5.c that was put in because our md5sum 
performance sucks?  You know _WHY_ our md5sum performance sucks?  Because 
md5_sha1_sum.c is reading and processing the file in 4 byte chunks.  
(sizeof() and RESERVE_CONFIG_BUFFER() don't mix.)

Right.  I _am_ ripping out the tangled #ifdefs.  After I track down this 
segfault...

Rob
-- 
Never bet against the cheap plastic solution.



More information about the busybox mailing list