diff options
| author | Hraban Luyat <hraban@0brg.net> | 2009-12-19 15:47:25 +0000 | 
|---|---|---|
| committer | Vijay Bellur <vijay@dev.gluster.com> | 2009-12-20 21:38:33 -0800 | 
| commit | 2a51ab19e6370325a5ebac9ed63f8606738919ec (patch) | |
| tree | b1de9f062e54c7df4582825ea88a4f2be5d7df58 | |
| parent | ea18fce5cd759a19aa928393a4b30cb87d33beec (diff) | |
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 <hraban@0brg.net>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 397 (dictionary serialization / deserialization fails on armv5tel)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=397
| -rw-r--r-- | libglusterfs/src/dict.c | 41 | 
1 files changed, 29 insertions, 12 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index e1c89a5b2ce..b8728ac1306 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;  | 
