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

Bug#366717: Method http has died unexpectedly (Packages/DiffIndex)



tags 366717 patch
thanks

Hi,

This is indeed due to an unaligned access in /usr/lib/apt/methods/http. A more complete backtrace:

(gdb) bt
#0  0xf7e4b5dc in LOAD_OP (I=0, W=0xff1f534c,
input=0x31d2b " `\n2.0\ncontrol.tar.gz 1142247192 0 0 100644 2022 `\n\037\213\b") at contrib/sha256.cc:64
#1  0xf7e4b794 in sha256_transform (state=0x59318,
input=0x31d2b " `\n2.0\ncontrol.tar.gz 1142247192 0 0 100644 2022 `\n\037\213\b") at contrib/sha256.cc:80
#2  0xf7e4f640 in SHA256Summation::Add (this=0x59310,
data=0x31ceb "!<arch>\ndebian-binary 1142247192 0 0 100644 4 `\n2.0\ncontrol.tar.gz 1142247192 0 0 100644 2022 `\n\037\213\b",
    len=1448) at contrib/sha256.cc:274
#3  0x00019bf4 in Hashes::Add (this=0x59248,
Data=0x31ceb "!<arch>\ndebian-binary 1142247192 0 0 100644 4 `\n2.0\ncontrol.tar.gz 1142247192 0 0 100644 2022 `\n\037\213\b",
    Size=1448) at hashes.h:38
#4  0x00013b40 in CircleBuf::Write (this=0x30cdc, Fd=4) at http.cc:226
#5  0x00016150 in HttpMethod::Go (this=0xff1f59a4, ToFile=true, Srv=0x30b48)
    at http.cc:799
#6  0x00016a54 in ServerState::RunData (this=0x30b48) at http.cc:497
#7  0x00018f64 in HttpMethod::Loop (this=0xff1f59a4) at http.cc:1143
#8  0x000193bc in main () at http.cc:1231

Offending code in contrib/sha256.cc:

62 static inline void LOAD_OP(int I, u32 *W, const u8 *input)
63 {
64         W[I] = ntohl( ((u32*)(input))[I] );
65 }

input is u8, so there are no restrictions on its alignment. When an attempt is made to cast it into u32, an unaligned access may result.

A quick-n-dirty patch is attached. It ensures that input array passed to LOAD_OP is always aligned on a 4-byte boundary by memcpy()'ing it into correctly aligned array before the call. I *believe* that sha256_transform() uses at most first 16*4=64 bytes of input array, so it's sufficient to memcpy() only that, but it would be nice if someone could actually look it over (or come up with a cleaner solution, that would work too :-).

Best regards,

Jurij Smakov                                        jurij@wooyd.org
Key: http://www.wooyd.org/pgpkey/                   KeyID: C99E03CC
diff -aur a/apt-pkg/contrib/sha256.cc b/apt-pkg/contrib/sha256.cc
--- a/apt-pkg/contrib/sha256.cc	2006-03-29 17:01:29.000000000 -0800
+++ b/apt-pkg/contrib/sha256.cc	2006-05-11 23:55:12.000000000 -0700
@@ -72,12 +72,14 @@
 static void sha256_transform(u32 *state, const u8 *input)
 {
         u32 a, b, c, d, e, f, g, h, t1, t2;
-        u32 W[64];
+        u32 W[64], aligned[16];
         int i;
 
+	/* make sure that we are word-aligned */
+	memcpy(aligned, input, 16*sizeof(u32));
         /* load the input */
         for (i = 0; i < 16; i++)
-                LOAD_OP(i, W, input);
+                LOAD_OP(i, W, (u8 *) aligned);
 
         /* now blend */
         for (i = 16; i < 64; i++)

Reply to: