From 2a51ab19e6370325a5ebac9ed63f8606738919ec Mon Sep 17 00:00:00 2001 From: Hraban Luyat Date: Sat, 19 Dec 2009 15:47:25 +0000 Subject: More robust dictionary (un)serialization (fixes bug #397). Hello, This patch fixes bug 397: dictionary (de)serialization used pointer casting which forced word-alignment on (at least) armv5tel, causing corruption while writing and reading buffers into memory. It also adds some debugging (more information in case of errors). I tried to send this a few times already but I think it got bounced from the list. Greetings, Hraban Luyat Signed-off-by: Hraban Luyat Signed-off-by: Vijay Bellur BUG: 397 (dictionary serialization / deserialization fails on armv5tel) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=397 --- libglusterfs/src/dict.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'libglusterfs') diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index e1c89a5b2..b8728ac13 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -2195,11 +2195,12 @@ out: int _dict_serialize (dict_t *this, char *buf) { - int ret = -1; - data_pair_t * pair = NULL; - int32_t count = 0; - int32_t keylen = 0; - int32_t vallen = 0; + int ret = -1; + data_pair_t * pair = NULL; + int32_t count = 0; + int32_t keylen = 0; + int32_t vallen = 0; + int32_t netword = 0; if (!buf) { gf_log ("dict", GF_LOG_ERROR, @@ -2213,7 +2214,8 @@ _dict_serialize (dict_t *this, char *buf) goto out; } - *(int32_t *) buf = hton32 (count); + netword = hton32 (count); + memcpy (buf, &netword, sizeof(netword)); buf += DICT_HDR_LEN; pair = this->members_list; @@ -2231,7 +2233,8 @@ _dict_serialize (dict_t *this, char *buf) } keylen = strlen (pair->key); - *(int32_t *) buf = hton32 (keylen); + netword = hton32 (keylen); + memcpy (buf, &netword, sizeof(netword)); buf += DICT_DATA_HDR_KEY_LEN; if (!pair->value) { @@ -2241,7 +2244,8 @@ _dict_serialize (dict_t *this, char *buf) } vallen = pair->value->len; - *(int32_t *) buf = hton32 (vallen); + netword = hton32 (vallen); + memcpy (buf, &netword, sizeof(netword)); buf += DICT_DATA_HDR_VAL_LEN; memcpy (buf, pair->key, keylen); @@ -2354,7 +2358,7 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill) char * key = NULL; int32_t keylen = 0; int32_t vallen = 0; - + int32_t hostord = 0; buf = orig_buf; @@ -2388,7 +2392,8 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill) goto out; } - count = ntoh32 (*(int32_t *) buf); + memcpy (&hostord, buf, sizeof(hostord)); + count = ntoh32 (hostord); buf += DICT_HDR_LEN; if (count < 0) { @@ -2402,22 +2407,32 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill) for (i = 0; i < count; i++) { if ((buf + DICT_DATA_HDR_KEY_LEN) > (orig_buf + size)) { + gf_log ("dict", GF_LOG_DEBUG, + "No room for keylen (size %d).", + DICT_DATA_HDR_KEY_LEN); gf_log ("dict", GF_LOG_ERROR, "undersized buffer passsed"); goto out; } - keylen = ntoh32 (*(int32_t *) buf); + memcpy (&hostord, buf, sizeof(hostord)); + keylen = ntoh32 (hostord); buf += DICT_DATA_HDR_KEY_LEN; if ((buf + DICT_DATA_HDR_VAL_LEN) > (orig_buf + size)) { + gf_log ("dict", GF_LOG_DEBUG, + "No room for vallen (size %d).", + DICT_DATA_HDR_VAL_LEN); gf_log ("dict", GF_LOG_ERROR, "undersized buffer passsed"); goto out; } - vallen = ntoh32 (*(int32_t *) buf); + memcpy (&hostord, buf, sizeof(hostord)); + vallen = ntoh32 (hostord); buf += DICT_DATA_HDR_VAL_LEN; if ((buf + keylen) > (orig_buf + size)) { + gf_log ("dict", GF_LOG_DEBUG, + "No room for key (size %d).", keylen); gf_log ("dict", GF_LOG_ERROR, "undersized buffer passsed"); goto out; @@ -2426,6 +2441,8 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill) buf += keylen + 1; /* for '\0' */ if ((buf + vallen) > (orig_buf + size)) { + gf_log ("dict", GF_LOG_DEBUG, + "No room for value (size %d).", vallen); gf_log ("dict", GF_LOG_ERROR, "undersized buffer passsed"); goto out; -- cgit