# HG changeset patch # User Jim Meyering # Date 1211811928 -7200 # Node ID 92a80b637ea19f5aadc6d81c6d3321ce4e0069d6 # Parent fc6baf7d0ac06484e165705532e6a4712804ec92 avoid unaligned access errors, e.g., on sparc * lib/sha512.c (sha512_conclude_ctx): Use set_uint64 rather than direct access through a possibly-unaligned uint64* pointer. * lib/sha256.c (sha256_conclude_ctx): Use set_uint32 rather than direct access through a possibly-unaligned uint32* pointer. Prompted by this patch from Tom "spot" Callaway: http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/13638 diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2008-05-26 Jim Meyering + avoid unaligned access errors, e.g., on sparc + * lib/sha512.c (sha512_conclude_ctx): Use set_uint64 rather than + direct access through a possibly-unaligned uint64* pointer. + * lib/sha256.c (sha256_conclude_ctx): Use set_uint32 rather than + direct access through a possibly-unaligned uint32* pointer. + Prompted by this patch from Tom "spot" Callaway: + http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/13638 + sha512.c: fix typo in comment * lib/sha512.c (sha512_conclude_ctx): Length is 128-bit, not 64-bit. diff --git a/lib/sha256.c b/lib/sha256.c --- a/lib/sha256.c +++ b/lib/sha256.c @@ -134,9 +134,13 @@ if (ctx->total[0] < bytes) ++ctx->total[1]; - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); - ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3); + /* Put the 64-bit file length in *bits* at the end of the buffer. + Use set_uint32 rather than a simple assignment, to avoid risk of + unaligned access. */ + set_uint32 ((char *) &ctx->buffer[size - 2], + SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29))); + set_uint32 ((char *) &ctx->buffer[size - 1], + SWAP (ctx->total[0] << 3)); memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); diff --git a/lib/sha512.c b/lib/sha512.c --- a/lib/sha512.c +++ b/lib/sha512.c @@ -141,10 +141,14 @@ if (u64lt (ctx->total[0], u64lo (bytes))) ctx->total[1] = u64plus (ctx->total[1], u64lo (1)); - /* Put the 128-bit file length in *bits* at the end of the buffer. */ - ctx->buffer[size - 2] = SWAP (u64or (u64shl (ctx->total[1], 3), - u64shr (ctx->total[0], 61))); - ctx->buffer[size - 1] = SWAP (u64shl (ctx->total[0], 3)); + /* Put the 128-bit file length in *bits* at the end of the buffer. + Use set_uint64 rather than a simple assignment, to avoid risk of + unaligned access. */ + set_uint64 ((char *) &ctx->buffer[size - 2], + SWAP (u64or (u64shl (ctx->total[1], 3), + u64shr (ctx->total[0], 61)))); + set_uint64 ((char *) &ctx->buffer[size - 1], + SWAP (u64shl (ctx->total[0], 3))); memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 8 - bytes);