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: 11.19.0-rc1~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9877139df3c401cffafeb30107df2735d9dbdda;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.c b/main/astobj2.c index b49ed60817..c434209d61 100644 --- a/main/astobj2.c +++ b/main/astobj2.c @@ -900,7 +900,7 @@ static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *use return NULL; } - i = abs(c->hash_fn(user_data, OBJ_POINTER)); + i = abs(c->hash_fn(user_data, OBJ_POINTER) % c->n_buckets); if (flags & OBJ_NOLOCK) { orig_lock = adjust_lock(c, AO2_LOCK_REQ_WRLOCK, 1); @@ -909,7 +909,6 @@ static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *use orig_lock = AO2_LOCK_REQ_MUTEX; } - i %= c->n_buckets; p->astobj = obj; p->version = ast_atomic_fetchadd_int(&c->version, 1); AST_LIST_INSERT_TAIL(&c->buckets[i], p, entry); @@ -1065,7 +1064,7 @@ static void *internal_ao2_callback(struct ao2_container *c, enum search_flags fl */ if ((flags & (OBJ_POINTER | OBJ_KEY))) { /* we know hash can handle this case */ - start = i = c->hash_fn(arg, flags & (OBJ_POINTER | OBJ_KEY)) % c->n_buckets; + start = i = abs(c->hash_fn(arg, flags & (OBJ_POINTER | OBJ_KEY)) % c->n_buckets); } else { /* don't know, let's scan all buckets */ start = i = -1; /* XXX this must be fixed later. */