Module: kamailio
Branch: master
Commit: 819f9eae0066a94081b0805dadf69bd57050e4f0
URL:
https://github.com/kamailio/kamailio/commit/819f9eae0066a94081b0805dadf69bd…
Author: Victor Seva <linuxmaniac(a)torreviejawireless.org>
Committer: Victor Seva <linuxmaniac(a)torreviejawireless.org>
Date: 2017-02-22T08:36:54+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
---
Modified: src/modules/usrloc/ucontact.c
Modified: src/modules/usrloc/urecord.c
---
Diff:
https://github.com/kamailio/kamailio/commit/819f9eae0066a94081b0805dadf69bd…
Patch:
https://github.com/kamailio/kamailio/commit/819f9eae0066a94081b0805dadf69bd…
---
diff --git a/src/modules/usrloc/ucontact.c b/src/modules/usrloc/ucontact.c
index a5531f4..630a4bd 100644
--- a/src/modules/usrloc/ucontact.c
+++ b/src/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/src/modules/usrloc/urecord.c b/src/modules/usrloc/urecord.c
index 0ff43c9..9223b85 100644
--- a/src/modules/usrloc/urecord.c
+++ b/src/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) {