[sr-dev] git:4.4:5b34d844: usrloc: fix ucontact shared leak

Victor Seva linuxmaniac at torreviejawireless.org
Wed Feb 22 09:21:32 CET 2017


Module: kamailio
Branch: 4.4
Commit: 5b34d844c2cf6caba5888f26789c1472802fb0b8
URL: https://github.com/kamailio/kamailio/commit/5b34d844c2cf6caba5888f26789c1472802fb0b8

Author: Victor Seva <linuxmaniac at torreviejawireless.org>
Committer: Victor Seva <linuxmaniac at torreviejawireless.org>
Date: 2017-02-22T09:20:05+01:00

usrloc: fix ucontact shared leak

keep a copy of urecord if mode is DB_ONLY as it is static
preventing leaking ucontact to shared memory

Fix #1000
See #997 for details

(cherry picked from commit 819f9eae0066a94081b0805dadf69bd57050e4f0)

---

Modified: modules/usrloc/ucontact.c
Modified: modules/usrloc/urecord.c

---

Diff:  https://github.com/kamailio/kamailio/commit/5b34d844c2cf6caba5888f26789c1472802fb0b8.diff
Patch: https://github.com/kamailio/kamailio/commit/5b34d844c2cf6caba5888f26789c1472802fb0b8.patch

---

diff --git a/modules/usrloc/ucontact.c b/modules/usrloc/ucontact.c
index 68e0359..ea0e8db 100644
--- a/modules/usrloc/ucontact.c
+++ b/modules/usrloc/ucontact.c
@@ -1672,6 +1672,7 @@ static inline int update_contact_db(ucontact_t* _c)
  */
 int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci)
 {
+	struct urecord _ur;
 	/* we have to update memory in any case, but database directly
 	 * only in db_mode 1 */
 	if (mem_update_ucontact( _c, _ci) < 0) {
@@ -1680,6 +1681,8 @@ int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci)
 	}
 
 	if (db_mode==DB_ONLY) {
+		/* urecord is static generate a copy for later */
+		if (_r) memcpy(&_ur, _r, sizeof(struct urecord));
 		if (update_contact_db(_c) < 0) return -1;
 	}
 
@@ -1690,8 +1693,14 @@ int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci)
 		run_ul_callbacks( UL_CONTACT_UPDATE, _c);
 	}
 
-	if (_r && db_mode!=DB_ONLY)
-		update_contact_pos( _r, _c);
+	if (_r) {
+		if (db_mode!=DB_ONLY) {
+			update_contact_pos( _r, _c);
+		} else {
+			/* urecord was static restore copy */
+			memcpy(_r, &_ur, sizeof(struct urecord));
+		}
+	}
 
 	st_update_ucontact(_c);
 
diff --git a/modules/usrloc/urecord.c b/modules/usrloc/urecord.c
index a6e7cec..821821d 100644
--- a/modules/usrloc/urecord.c
+++ b/modules/usrloc/urecord.c
@@ -568,12 +568,16 @@ void release_urecord(urecord_t* _r)
 int insert_ucontact(urecord_t* _r, str* _contact, ucontact_info_t* _ci,
 															ucontact_t** _c)
 {
+	struct urecord _ur;
 	if ( ((*_c)=mem_insert_ucontact(_r, _contact, _ci)) == 0) {
 		LM_ERR("failed to insert contact\n");
 		return -1;
 	}
 
 	if (db_mode==DB_ONLY) {
+		/* urecord is static generate a copy for later */
+		memcpy(&_ur, _r, sizeof(struct urecord));
+
 		if (db_insert_ucontact(*_c) < 0) {
 			LM_ERR("failed to insert in database\n");
 			return -1;
@@ -586,13 +590,19 @@ int insert_ucontact(urecord_t* _r, str* _contact, ucontact_info_t* _ci,
 		run_ul_callbacks( UL_CONTACT_INSERT, *_c);
 	}
 
-	if (db_mode == WRITE_THROUGH) {
-		if (db_insert_ucontact(*_c) < 0) {
-			LM_ERR("failed to insert in database\n");
-			return -1;
-		} else {
-			(*_c)->state = CS_SYNC;
-		}
+	switch (db_mode) {
+		case WRITE_THROUGH:
+			if (db_insert_ucontact(*_c) < 0) {
+				LM_ERR("failed to insert in database\n");
+				return -1;
+			} else {
+				(*_c)->state = CS_SYNC;
+			}
+		break;
+		case DB_ONLY:
+			/* urecord was static restore copy */
+			memcpy(_r, &_ur, sizeof(struct urecord));
+		break;
 	}
 
 	return 0;
@@ -608,11 +618,22 @@ int insert_ucontact(urecord_t* _r, str* _contact, ucontact_info_t* _ci,
 int delete_ucontact(urecord_t* _r, struct ucontact* _c)
 {
 	int ret = 0;
+	struct urecord _ur;
+
+	if (db_mode==DB_ONLY) {
+		/* urecord is static generate a copy for later */
+		memcpy(&_ur, _r, sizeof(struct urecord));
+	}
 
 	if (exists_ulcb_type(UL_CONTACT_DELETE)) {
 		run_ul_callbacks( UL_CONTACT_DELETE, _c);
 	}
 
+	if (db_mode==DB_ONLY) {
+		/* urecord was static restore copy */
+		memcpy(_r, &_ur, sizeof(struct urecord));
+	}
+
 	if (st_delete_ucontact(_c) > 0) {
 		if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
 			if (db_delete_ucontact(_c) < 0) {




More information about the sr-dev mailing list