mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-10 20:08:16 +00:00
rtp_engine.c: Fix deadlock potential copying RTP payload maps.
There is a theoretical potential to deadlock in ast_rtp_codecs_payloads_copy() because it locks two different ast_rtp_codecs locks. It is theoretical because the callers of the function are either copying between a local ast_rtp_codecs struct and a RTP instance of the ast_rtp_codecs struct. Or they are copying between the caller and callee channel RTP instances before initiating the call to the callee. Neither of these situations could actually result in a deadlock because there cannot be another thread involved at the time. * Add deadlock avoidance code to ast_rtp_codecs_payloads_copy() since it locks two ast_rtp_codecs locks to perform a copy. This only affects v13 since this deadlock avoidance code is already in newer branches. Change-Id: I1aa0b168f94049bd59bbd74a85bd1e78718f09e5
This commit is contained in:
@@ -708,9 +708,15 @@ void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_cod
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ast_rwlock_rdlock(&src->codecs_lock);
|
|
||||||
ast_rwlock_wrlock(&dest->codecs_lock);
|
ast_rwlock_wrlock(&dest->codecs_lock);
|
||||||
|
|
||||||
|
/* Deadlock avoidance because of held write lock. */
|
||||||
|
while (ast_rwlock_tryrdlock(&src->codecs_lock)) {
|
||||||
|
ast_rwlock_unlock(&dest->codecs_lock);
|
||||||
|
sched_yield();
|
||||||
|
ast_rwlock_wrlock(&dest->codecs_lock);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < AST_VECTOR_SIZE(&src->payloads); i++) {
|
for (i = 0; i < AST_VECTOR_SIZE(&src->payloads); i++) {
|
||||||
struct ast_rtp_payload_type *type;
|
struct ast_rtp_payload_type *type;
|
||||||
|
|
||||||
@@ -732,8 +738,8 @@ void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_cod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest->framing = src->framing;
|
dest->framing = src->framing;
|
||||||
ast_rwlock_unlock(&dest->codecs_lock);
|
|
||||||
ast_rwlock_unlock(&src->codecs_lock);
|
ast_rwlock_unlock(&src->codecs_lock);
|
||||||
|
ast_rwlock_unlock(&dest->codecs_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
|
void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
|
||||||
|
|||||||
Reference in New Issue
Block a user