[asterisk-commits] Fix creation race of contact status structures. (asterisk[master])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Feb 15 15:39:47 CST 2016


Anonymous Coward #1000019 has submitted this change and it was merged.

Change subject: Fix creation race of contact_status structures.
......................................................................


Fix creation race of contact_status structures.

It is possible when processing a SIP REGISTER request to have two
threads end up creating contact_status structures in sorcery.
contact_status is created using a "find or create" function. If two
threads call into this at the same time, each thread will fail to find
an existing contact_status, and so both will end up creating a new
contact status.

During testing, we would see sporadic failures because the
PJSIP_CONTACT() dialplan function would operate on a different
contact_status than what had been updated by res_pjsip/pjsip_options.

The fix here is two-fold:
1) The "find or create" function for contact_status now has a lock
around the entire operation. This way, if two threads attempt the
operation simultaneously, the first to get there will create the object,
and the second will find the object created by the first thread.

2) res_sorcery_memory has had its create callback updated so that it
will not allow for objects with duplicate IDs to be created.

Change-Id: I55b1460ff1eb0af0a3697b82d7c2bac9f6af5b97
---
M res/res_pjsip/pjsip_options.c
M res/res_sorcery_memory.c
2 files changed, 18 insertions(+), 1 deletion(-)

Approvals:
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, approved
  George Joseph: Looks good to me, but someone else must approve



diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 089703b..73f12a0 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -107,6 +107,8 @@
 	return status;
 }
 
+AST_MUTEX_DEFINE_STATIC(creation_lock);
+
 /*!
  * \brief Retrieve a ast_sip_contact_status object from sorcery creating
  *        one if not found.
@@ -114,6 +116,7 @@
 struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const struct ast_sip_contact *contact)
 {
 	struct ast_sip_contact_status *status;
+	SCOPED_MUTEX(lock, &creation_lock);
 
 	status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS,
 		ast_sorcery_object_get_id(contact));
diff --git a/res/res_sorcery_memory.c b/res/res_sorcery_memory.c
index 1532358..95cb248 100644
--- a/res/res_sorcery_memory.c
+++ b/res/res_sorcery_memory.c
@@ -98,7 +98,21 @@
 
 static int sorcery_memory_create(const struct ast_sorcery *sorcery, void *data, void *object)
 {
-	ao2_link(data, object);
+	void *existing;
+
+	ao2_lock(data);
+
+	existing = ao2_find(data, ast_sorcery_object_get_id(object), OBJ_KEY | OBJ_NOLOCK);
+	if (existing) {
+		ao2_ref(existing, -1);
+		ao2_unlock(data);
+		return -1;
+	}
+
+	ao2_link_flags(data, object, OBJ_NOLOCK);
+
+	ao2_unlock(data);
+
 	return 0;
 }
 

-- 
To view, visit https://gerrit.asterisk.org/2250
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I55b1460ff1eb0af0a3697b82d7c2bac9f6af5b97
Gerrit-PatchSet: 2
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: George Joseph <george.joseph at fairview5.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>



More information about the asterisk-commits mailing list