From: Ivan Poddubny Date: Sun, 24 May 2015 18:47:16 +0000 (+0300) Subject: Astobj2: Correctly treat hash_fn returning INT_MIN X-Git-Tag: 13.5.0-rc1~118^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=97a6ce1717bd0c4b1b4305f10f13fd5ec9bb7441;p=thirdparty%2Fasterisk.git Astobj2: Correctly treat hash_fn returning INT_MIN The code in astobj2_hash.c wrongly assumed that abs(int) is always > 0. However, abs(INT_MIN) = INT_MIN and is still negative, as well as abs(INT_MIN) % num_buckets, and as a result this led to a crash. One way to trigger the bug is using host=::80 or 0.0.0.128 in peer configuration section in chan_sip or chan_iax. This patch takes the remainder before applying abs, so that bucket number is always in range. ASTERISK-25100 #close Reported by: Mark Petersen Change-Id: Id6981400ad526f47e10bcf7b847b62bd2785e899 --- diff --git a/main/astobj2_hash.c b/main/astobj2_hash.c index 066999f495..1cd6ee2490 100644 --- a/main/astobj2_hash.c +++ b/main/astobj2_hash.c @@ -235,8 +235,7 @@ static struct hash_bucket_node *hash_ao2_new_node(struct ao2_container_hash *sel return NULL; } - i = abs(self->hash_fn(obj_new, OBJ_SEARCH_OBJECT)); - i %= self->n_buckets; + i = abs(self->hash_fn(obj_new, OBJ_SEARCH_OBJECT) % self->n_buckets); if (tag) { __ao2_ref_debug(obj_new, +1, tag, file, line, func); @@ -386,8 +385,8 @@ static struct hash_bucket_node *hash_ao2_find_first(struct ao2_container_hash *s case OBJ_SEARCH_OBJECT: case OBJ_SEARCH_KEY: /* we know hash can handle this case */ - bucket_cur = abs(self->hash_fn(arg, flags & OBJ_SEARCH_MASK)); - bucket_cur %= self->n_buckets; + bucket_cur = abs(self->hash_fn(arg, flags & OBJ_SEARCH_MASK) + % self->n_buckets); state->sort_fn = self->common.sort_fn; break; case OBJ_SEARCH_PARTIAL_KEY: @@ -984,8 +983,8 @@ static int hash_ao2_integrity(struct ao2_container_hash *self) ++count_obj; /* Check container hash key for expected bucket. */ - bucket_exp = abs(self->hash_fn(node->common.obj, OBJ_SEARCH_OBJECT)); - bucket_exp %= self->n_buckets; + bucket_exp = abs(self->hash_fn(node->common.obj, OBJ_SEARCH_OBJECT) + % self->n_buckets); if (bucket != bucket_exp) { ast_log(LOG_ERROR, "Bucket %d node hashes to bucket %d!\n", bucket, bucket_exp);