]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Fix unaligned access in SipHash-2-4.
authorYawning Angel <yawning@schwanenlied.me>
Sun, 22 Mar 2015 22:31:08 +0000 (22:31 +0000)
committerNick Mathewson <nickm@torproject.org>
Mon, 23 Mar 2015 13:20:02 +0000 (09:20 -0400)
The compiler is allowed to assume that a "uint64_t *" is aligned
correctly, and will inline a version of memcpy that acts as such.

Use "uint8_t *", so the compiler does the right thing.

changes/bug15436 [new file with mode: 0644]
src/ext/csiphash.c

diff --git a/changes/bug15436 b/changes/bug15436
new file mode 100644 (file)
index 0000000..4fa44d1
--- /dev/null
@@ -0,0 +1,4 @@
+  o Minor bugfixes (portability):
+    - Use the correct datatype in the SipHash-2-4 function to prevent compilers
+      from assuming any sort of alignment.  Fixes bug 15436; bugfix on
+      0.2.5.3-alpha.
index c24788603819246c02eba100564727d2c690acfb..979990f639b61a29f001dc10e754ccf52270827a 100644 (file)
@@ -100,10 +100,18 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k
        uint64_t k0 = key->k0;
        uint64_t k1 = key->k1;
        uint64_t b = (uint64_t)src_sz << 56;
+#ifdef UNALIGNED_OK
        const uint64_t *in = (uint64_t*)src;
+#else
+       /* On platforms where alignment matters, if 'in' is a pointer to a
+        * datatype that must be aligned, the compiler is allowed to
+        * generate code that assumes that it is aligned as such.
+        */
+       const uint8_t *in = (uint8_t *)src;
+#endif
 
-        uint64_t t;
-        uint8_t *pt, *m;
+       uint64_t t;
+       uint8_t *pt, *m;
 
        uint64_t v0 = k0 ^ 0x736f6d6570736575ULL;
        uint64_t v1 = k1 ^ 0x646f72616e646f6dULL;
@@ -113,12 +121,14 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k
        while (src_sz >= 8) {
 #ifdef UNALIGNED_OK
                uint64_t mi = _le64toh(*in);
+               in += 1;
 #else
                uint64_t mi;
                memcpy(&mi, in, 8);
                mi = _le64toh(mi);
+               in += 8;
 #endif
-               in += 1; src_sz -= 8;
+               src_sz -= 8;
                v3 ^= mi;
                DOUBLE_ROUND(v0,v1,v2,v3);
                v0 ^= mi;