From 814d39945eedc78f4d06bbc90b44ffb03d34f05b Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Mon, 16 Jan 2017 14:46:11 +0100 Subject: [PATCH] tm: sanitizied sip msg cloner --- src/modules/tm/sip_msg.c | 55 +++++++++++++++++++-------------------- src/modules/tm/sip_msg.h | 56 ++++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/src/modules/tm/sip_msg.c b/src/modules/tm/sip_msg.c index 694a6e8e5cf..b4bdcc3c856 100644 --- a/src/modules/tm/sip_msg.c +++ b/src/modules/tm/sip_msg.c @@ -22,18 +22,18 @@ /** * @file * @brief TM :: Message cloning functionality - * + * * Cloning a message into shared memory (TM keeps a snapshot * of messages in memory); note that many operations, which * allocate pkg memory (such as parsing) cannot be used with * a cloned message -- it would result in linking pkg structures * to shmem msg and eventually in a memory error. - * + * * The cloned message is stored in a single memory fragment to * save too many shm_mallocs -- these are expensive as they * not only take lookup in fragment table but also a shmem lock * operation (the same for shm_free) - * + * * Allow postponing the cloning of SIP msg: * t_newtran() copies the requests to shm mem without the lumps, * and t_forward_nonack() clones the lumps later when it is called @@ -56,16 +56,17 @@ /** * @brief Clone a SIP message - * @warning Cloner does not clone all hdr_field headers (From, To, etc.). Pointers will reference pkg memory. Dereferencing will crash ser! + * @warning Cloner does not clone all hdr_field headers (From, To, etc.). + * Pointers will reference pkg memory. Dereferencing will crash app! * @param org_msg Original SIP message * @param sip_msg_len Length of the SIP message * @return Cloned SIP message, or NULL on error */ -struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len ) +struct sip_msg *sip_msg_cloner(struct sip_msg *org_msg, int *sip_msg_len) { - /* take care of the lumps only for replies if the msg cloning is + /* take care of the lumps only for replies if the msg cloning is postponed */ - if (org_msg->first_line.type==SIP_REPLY) + if(org_msg->first_line.type == SIP_REPLY) /*cloning all the lumps*/ return sip_msg_shm_clone(org_msg, sip_msg_len, 1); /* don't clone the lumps */ @@ -78,61 +79,59 @@ struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len ) unsigned char lumps_are_cloned = 0; - /** * @brief Wrapper function for msg_lump_cloner() with some additional sanity checks * @param shm_msg SIP message in shared memory * @param pkg_msg SIP message in private memory * @return 0 on success, -1 on error */ -int save_msg_lumps( struct sip_msg *shm_msg, struct sip_msg *pkg_msg) +int save_msg_lumps(struct sip_msg *shm_msg, struct sip_msg *pkg_msg) { int ret; - struct lump* add_rm; - struct lump* body_lumps; - struct lump_rpl* reply_lump; - + struct lump *add_rm; + struct lump *body_lumps; + struct lump_rpl *reply_lump; + /* make sure that we do not clone the lumps twice */ - if (lumps_are_cloned) { - LOG(L_DBG, "DEBUG: save_msg_lumps: lumps have been already cloned\n" ); + if(lumps_are_cloned) { + LM_DBG("lumps have been already cloned\n"); return 0; } /* sanity checks */ - if (unlikely(!shm_msg || ((shm_msg->msg_flags & FL_SHM_CLONE)==0))) { - LOG(L_ERR, "ERROR: save_msg_lumps: BUG, there is no shmem-ized message" - " (shm_msg=%p)\n", shm_msg); + if(unlikely(!shm_msg || ((shm_msg->msg_flags & FL_SHM_CLONE) == 0))) { + LM_ERR("BUG - there is no shmem-ized message (shm_msg=%p)\n", shm_msg); return -1; } - if (unlikely(shm_msg->first_line.type!=SIP_REQUEST)) { - LOG(L_ERR, "ERROR: save_msg_lumps: BUG, the function should be called only for requests\n" ); + if(unlikely(shm_msg->first_line.type != SIP_REQUEST)) { + LM_ERR("BUG - the function should be called only for requests\n"); return -1; } #ifdef EXTRA_DEBUG membar_depends(); - if (shm_msg->add_rm || shm_msg->body_lumps || shm_msg->reply_lump) { - LOG(L_ERR, "ERROR: save_msg_lumps: BUG, trying to overwrite the already cloned lumps\n"); + if(shm_msg->add_rm || shm_msg->body_lumps || shm_msg->reply_lump) { + LM_ERR("BUG - trying to overwrite the already cloned lumps\n"); return -1; } #endif /* needless to clone the lumps for ACK, they will not be used again */ - if (shm_msg->REQ_METHOD == METHOD_ACK) + if(shm_msg->REQ_METHOD == METHOD_ACK) return 0; - /* clean possible previous added vias/clen header or else they would + /* clean possible previous added vias/clen header or else they would * get propagated in the failure routes */ free_via_clen_lump(&pkg_msg->add_rm); lumps_are_cloned = 1; - ret=msg_lump_cloner(pkg_msg, &add_rm, &body_lumps, &reply_lump); - if (likely(ret==0)){ + ret = msg_lump_cloner(pkg_msg, &add_rm, &body_lumps, &reply_lump); + if(likely(ret == 0)) { /* make sure the lumps are fully written before adding them to - shm_msg (in case someone accesses it in the same time) */ + * shm_msg (in case someone accesses it in the same time) */ membar_write(); shm_msg->add_rm = add_rm; shm_msg->body_lumps = body_lumps; shm_msg->reply_lump = reply_lump; } - return ret<0?-1:0; + return ret < 0 ? -1 : 0; } diff --git a/src/modules/tm/sip_msg.h b/src/modules/tm/sip_msg.h index 96e779903d4..9d818d9310a 100644 --- a/src/modules/tm/sip_msg.h +++ b/src/modules/tm/sip_msg.h @@ -13,26 +13,26 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * @brief TM :: Message cloning functionality - * + * * Cloning a message into shared memory (TM keeps a snapshot * of messages in memory); note that many operations, which * allocate pkg memory (such as parsing) cannot be used with * a cloned message -- it would result in linking pkg structures * to shmem msg and eventually in a memory error. - * + * * The cloned message is stored in a single memory fragment to * save too many shm_mallocs -- these are expensive as they * not only take lookup in fragment table but also a shmem lock * operation (the same for shm_free) - * + * * Allow postponing the cloning of SIP msg: * t_newtran() copies the requests to shm mem without the lumps, * and t_forward_nonack() clones the lumps later when it is called @@ -54,49 +54,49 @@ /** * @brief Helper function to free a SIP message - * + * * msg is a reply: one memory block was allocated - * + * * msg is a request: two memory blocks were allocated: * - one for the sip_msg struct * - another one for the lumps which is linked to add_rm, body_lumps, * or reply_lump */ -#define _sip_msg_free(_free_func, _p_msg) \ - do{ \ - if (_p_msg->first_line.type==SIP_REPLY) { \ - _free_func( (_p_msg) ); \ - } else { \ - membar_depends(); \ - if ((_p_msg)->add_rm) \ - _free_func((_p_msg)->add_rm); \ - else if ((_p_msg)->body_lumps) \ - _free_func((_p_msg)->body_lumps); \ - else if ((_p_msg)->reply_lump) \ - _free_func((_p_msg)->reply_lump); \ - \ - _free_func( (_p_msg) ); \ - } \ - }while(0) +#define _sip_msg_free(_free_func, _p_msg) \ + do { \ + if(_p_msg->first_line.type == SIP_REPLY) { \ + _free_func((_p_msg)); \ + } else { \ + membar_depends(); \ + if((_p_msg)->add_rm) \ + _free_func((_p_msg)->add_rm); \ + else if((_p_msg)->body_lumps) \ + _free_func((_p_msg)->body_lumps); \ + else if((_p_msg)->reply_lump) \ + _free_func((_p_msg)->reply_lump); \ + _free_func((_p_msg)); \ + } \ + } while(0) /** * @brief Free a SIP message safely, with locking */ -#define sip_msg_free(_p_msg) _sip_msg_free(shm_free, _p_msg) +#define sip_msg_free(_p_msg) _sip_msg_free(shm_free, _p_msg) /** * @brief Free a SIP message unsafely, without locking */ -#define sip_msg_free_unsafe(_p_msg) _sip_msg_free(shm_free_unsafe, _p_msg) +#define sip_msg_free_unsafe(_p_msg) _sip_msg_free(shm_free_unsafe, _p_msg) /** * @brief Clone a SIP message - * @warning Cloner does not clone all hdr_field headers (From, To, etc.). Pointers will reference pkg memory. Dereferencing will crash ser! + * @warning Cloner does not clone all hdr_field headers (From, To, etc.). + * Pointers will reference pkg memory. Dereferencing will crash the app! * @param org_msg Original SIP message * @param sip_msg_len Length of the SIP message * @return Cloned SIP message, or NULL on error */ -struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len ); +struct sip_msg *sip_msg_cloner(struct sip_msg *org_msg, int *sip_msg_len); /** * @brief Indicates wheter we have already cloned the msg lumps or not @@ -109,7 +109,7 @@ extern unsigned char lumps_are_cloned; * @param pkg_msg SIP message in private memory * @return 0 on success, -1 on error */ -int save_msg_lumps( struct sip_msg *shm_msg, struct sip_msg *pkg_msg); +int save_msg_lumps(struct sip_msg *shm_msg, struct sip_msg *pkg_msg); #endif