diff options
author | Nick Mathewson <nickm@torproject.org> | 2009-03-02 19:15:05 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-03-02 19:15:05 +0000 |
commit | 9f8d095e0fa66dfa5087d5d23028b5caa3a87989 (patch) | |
tree | 25a414ab2b342e34f3aff851e76a358269ec40a8 | |
parent | aa154d846afaf38efeaf44bc55af6fc26bb180bd (diff) | |
download | tor-9f8d095e0fa66dfa5087d5d23028b5caa3a87989.tar.gz tor-9f8d095e0fa66dfa5087d5d23028b5caa3a87989.zip |
Add and use set/get_uint64 on onion tags. [bug 604; backportable]
It seems that 64-bit Sparc Solaris demands 64-bit-aligned access to
uint64_t, but does not 64-bit-align the stack-allocated char array we
use for cpuworker tags. So this patch adds a set/get_uint64 pair, and
uses them to access the conn_id field in the tag.
svn:r18743
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/common/compat.c | 26 | ||||
-rw-r--r-- | src/common/compat.h | 2 | ||||
-rw-r--r-- | src/or/cpuworker.c | 8 |
4 files changed, 33 insertions, 6 deletions
@@ -36,6 +36,9 @@ Changes in version 0.2.1.13-????? - 2009-02-?? timed out. Bugfix on 0.1.2.1-alpha; our CLEAR debugging code had been suppressing the bug since 0.1.2.10-alpha. Partial fix for bug 929. + - Do not assume that a stack-allocated character array will be + 64-bit aligned on platforms that demand that uint64_t access is + aligned. Possible fix for bug 604. o Minor features: - On Linux, use the prctl call to re-enable core dumps when the user diff --git a/src/common/compat.c b/src/common/compat.c index 23efe0b656..8fd6d9bc15 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -449,8 +449,21 @@ get_uint32(const char *cp) return v; } /** + * Read a 32-bit value beginning at <b>cp</b>. Equivalent to + * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid + * unaligned memory access. + */ +uint64_t +get_uint64(const char *cp) +{ + uint64_t v; + memcpy(&v,cp,8); + return v; +} + +/** * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to - * *(uint16_t)(cp) = v, but will not cause segfaults on platforms that forbid + * *(uint16_t*)(cp) = v, but will not cause segfaults on platforms that forbid * unaligned memory access. */ void set_uint16(char *cp, uint16_t v) @@ -459,13 +472,22 @@ set_uint16(char *cp, uint16_t v) } /** * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to - * *(uint32_t)(cp) = v, but will not cause segfaults on platforms that forbid + * *(uint32_t*)(cp) = v, but will not cause segfaults on platforms that forbid * unaligned memory access. */ void set_uint32(char *cp, uint32_t v) { memcpy(cp,&v,4); } +/** + * Set a 64-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to + * *(uint64_t*)(cp) = v, but will not cause segfaults on platforms that forbid + * unaligned memory access. */ +void +set_uint64(char *cp, uint64_t v) +{ + memcpy(cp,&v,8); +} /** * Rename the file <b>from</b> to the file <b>to</b>. On unix, this is diff --git a/src/common/compat.h b/src/common/compat.h index 7e8c83a297..b80bdd1222 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -450,8 +450,10 @@ const char *get_uname(void); uint16_t get_uint16(const char *cp) ATTR_PURE ATTR_NONNULL((1)); uint32_t get_uint32(const char *cp) ATTR_PURE ATTR_NONNULL((1)); +uint64_t get_uint64(const char *cp) ATTR_PURE ATTR_NONNULL((1)); void set_uint16(char *cp, uint16_t v) ATTR_NONNULL((1)); void set_uint32(char *cp, uint32_t v) ATTR_NONNULL((1)); +void set_uint64(char *cp, uint64_t v) ATTR_NONNULL((1)); /* These uint8 variants are defined to make the code more uniform. */ #define get_uint8(cp) (*(const uint8_t*)(cp)) diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index 88a72886eb..99e06df35e 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -63,8 +63,8 @@ static void tag_pack(char *tag, uint64_t conn_id, circid_t circ_id) { /*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/ - *(uint64_t *)tag = conn_id; - *(uint16_t *)(tag+8) = circ_id; + set_uint64(tag, conn_id); + set_uint16(tag+8, circ_id); } /** Unpack <b>tag</b> into addr, port, and circ_id. @@ -72,8 +72,8 @@ tag_pack(char *tag, uint64_t conn_id, circid_t circ_id) static void tag_unpack(const char *tag, uint64_t *conn_id, circid_t *circ_id) { - *conn_id = *(const uint64_t *)tag; - *circ_id = *(const uint16_t *)(tag+8); + *conn_id = get_uint64(tag); + *circ_id = get_uint16(tag+8); } /** Called when the onion key has changed and we need to spawn new |