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
This commit is contained in:
Nick Mathewson 2009-03-02 19:15:05 +00:00
parent aa154d846a
commit 9f8d095e0f
4 changed files with 33 additions and 6 deletions

View File

@ -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 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 had been suppressing the bug since 0.1.2.10-alpha. Partial fix
for bug 929. 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: o Minor features:
- On Linux, use the prctl call to re-enable core dumps when the user - On Linux, use the prctl call to re-enable core dumps when the user

View File

@ -448,9 +448,22 @@ get_uint32(const char *cp)
memcpy(&v,cp,4); memcpy(&v,cp,4);
return v; 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 * 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. */ * unaligned memory access. */
void void
set_uint16(char *cp, uint16_t v) 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 * 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. */ * unaligned memory access. */
void void
set_uint32(char *cp, uint32_t v) set_uint32(char *cp, uint32_t v)
{ {
memcpy(cp,&v,4); 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 * Rename the file <b>from</b> to the file <b>to</b>. On unix, this is

View File

@ -450,8 +450,10 @@ const char *get_uname(void);
uint16_t get_uint16(const char *cp) ATTR_PURE ATTR_NONNULL((1)); uint16_t get_uint16(const char *cp) ATTR_PURE ATTR_NONNULL((1));
uint32_t get_uint32(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_uint16(char *cp, uint16_t v) ATTR_NONNULL((1));
void set_uint32(char *cp, uint32_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. */ /* These uint8 variants are defined to make the code more uniform. */
#define get_uint8(cp) (*(const uint8_t*)(cp)) #define get_uint8(cp) (*(const uint8_t*)(cp))

View File

@ -63,8 +63,8 @@ static void
tag_pack(char *tag, uint64_t conn_id, circid_t circ_id) tag_pack(char *tag, uint64_t conn_id, circid_t circ_id)
{ {
/*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/ /*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/
*(uint64_t *)tag = conn_id; set_uint64(tag, conn_id);
*(uint16_t *)(tag+8) = circ_id; set_uint16(tag+8, circ_id);
} }
/** Unpack <b>tag</b> into addr, port, and 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 static void
tag_unpack(const char *tag, uint64_t *conn_id, circid_t *circ_id) tag_unpack(const char *tag, uint64_t *conn_id, circid_t *circ_id)
{ {
*conn_id = *(const uint64_t *)tag; *conn_id = get_uint64(tag);
*circ_id = *(const uint16_t *)(tag+8); *circ_id = get_uint16(tag+8);
} }
/** Called when the onion key has changed and we need to spawn new /** Called when the onion key has changed and we need to spawn new