Module: kamailio Branch: 4.4 Commit: 5b34d844c2cf6caba5888f26789c1472802fb0b8 URL: https://github.com/kamailio/kamailio/commit/5b34d844c2cf6caba5888f26789c1472...
Author: Victor Seva linuxmaniac@torreviejawireless.org Committer: Victor Seva linuxmaniac@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/5b34d844c2cf6caba5888f26789c1472... Patch: https://github.com/kamailio/kamailio/commit/5b34d844c2cf6caba5888f26789c1472...
---
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) {