mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-20 08:40:16 +00:00
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
This commit is contained in:
@@ -900,7 +900,7 @@ static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *use
|
|||||||
return NULL;
|
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) {
|
if (flags & OBJ_NOLOCK) {
|
||||||
orig_lock = adjust_lock(c, AO2_LOCK_REQ_WRLOCK, 1);
|
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;
|
orig_lock = AO2_LOCK_REQ_MUTEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
i %= c->n_buckets;
|
|
||||||
p->astobj = obj;
|
p->astobj = obj;
|
||||||
p->version = ast_atomic_fetchadd_int(&c->version, 1);
|
p->version = ast_atomic_fetchadd_int(&c->version, 1);
|
||||||
AST_LIST_INSERT_TAIL(&c->buckets[i], p, entry);
|
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))) {
|
if ((flags & (OBJ_POINTER | OBJ_KEY))) {
|
||||||
/* we know hash can handle this case */
|
/* 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 {
|
} else {
|
||||||
/* don't know, let's scan all buckets */
|
/* don't know, let's scan all buckets */
|
||||||
start = i = -1; /* XXX this must be fixed later. */
|
start = i = -1; /* XXX this must be fixed later. */
|
||||||
|
|||||||
Reference in New Issue
Block a user