Module: kamailio
Branch: master
Commit: 819f9eae0066a94081b0805dadf69bd57050e4f0
URL: 
https://github.com/kamailio/kamailio/commit/819f9eae0066a94081b0805dadf69bd57050e4f0

Author: Victor Seva <linuxman...@torreviejawireless.org>
Committer: Victor Seva <linuxman...@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/819f9eae0066a94081b0805dadf69bd57050e4f0.diff
Patch: 
https://github.com/kamailio/kamailio/commit/819f9eae0066a94081b0805dadf69bd57050e4f0.patch

---

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) {


_______________________________________________
sr-dev mailing list
sr-dev@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to