tm: safety checks for branch request len
authorDaniel-Constantin Mierla <miconda@gmail.com>
Thu, 14 May 2020 18:37:09 +0000 (20:37 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Thu, 14 May 2020 18:38:22 +0000 (20:38 +0200)
src/modules/tm/t_cancel.c
src/modules/tm/t_fwd.c
src/modules/tm/t_msgbuilder.c
src/modules/tm/t_reply.c
src/modules/tm/uac.c

index 39f9831..69fdb9f 100644 (file)
@@ -293,8 +293,12 @@ int cancel_branch( struct cell *t, int branch,
                                                                , reason
                                                                );
        }
-       if (!cancel) {
+       if (!cancel || len<=0) {
                LM_ERR("attempt to build a CANCEL failed\n");
+               if(cancel) {
+                       shm_free(cancel);
+                       cancel = NULL;
+               }
                /* remove BUSY_BUFFER -- mark cancel buffer as not used */
                pcbuf=&crb->buffer; /* workaround for type punning warnings */
                atomic_set_long(pcbuf, 0);
@@ -500,8 +504,12 @@ unsigned int t_uac_cancel( str *headers, str *body,
        cancel->dst.proto           = invite->dst.proto;
        //cancel->dst.proto_reserved1 = invite->dst.proto_reserved1;
 
-       if(!(buf = build_uac_cancel(headers,body,t_invite,0,&len,
-                                       &(cancel->dst)))){
+       buf = build_uac_cancel(headers, body, t_invite, 0, &len, &(cancel->dst));
+       if(!buf || len<=0) {
+               if(buf) {
+                       shm_free(buf);
+                       buf = NULL;
+               }
                ret=0;
                LM_ERR("attempt to build a CANCEL failed\n");
                goto error1;
index 1c662a4..e76e12c 100644 (file)
@@ -474,8 +474,12 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
        }
        /* ... and build it now */
        shbuf=build_req_buf_from_sip_req( i_req, &len, dst, BUILD_IN_SHM);
-       if (!shbuf) {
+       if (!shbuf || len<=0) {
                LM_ERR("could not build request\n");
+               if(shbuf) {
+                       shm_free(shbuf);
+                       shbuf = NULL;
+               }
                ret=E_OUT_OF_MEM;
                goto error01;
        }
@@ -883,7 +887,11 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
        shbuf=print_uac_request_from_buf( t, request, branch, uri,
                        &len, &t->uac[branch].request.dst,
                        buf, buf_len);
-       if (!shbuf) {
+       if (!shbuf || len<=0) {
+               if(shbuf) {
+                       shm_free(shbuf);
+                       shbuf = NULL;
+               }
                ret=ser_error=E_OUT_OF_MEM;
                goto error;
        }
@@ -1109,7 +1117,11 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
                                CANCEL_LEN, &t_invite->to
                                , 0
                                );
-               if (unlikely(!shbuf)) {
+               if (unlikely(!shbuf) || len<=0) {
+                       if(shbuf) {
+                               shm_free(shbuf);
+                               shbuf = NULL;
+                       }
                        LM_ERR("printing e2e cancel failed\n");
                        ret=ser_error=E_OUT_OF_MEM;
                        goto error;
index 75f0ab7..bd99524 100644 (file)
@@ -252,7 +252,7 @@ error:
  *
  * Can not be used to build other type of requests!
  */
-char *build_local_reparse(struct cell *Trans,unsigned int branch,
+char *build_local_reparse(tm_cell_t *Trans,unsigned int branch,
        unsigned int *len, char *method, int method_len, str *to
        , struct cancel_reason *reason
        )
@@ -272,7 +272,7 @@ char *build_local_reparse(struct cell *Trans,unsigned int branch,
        invite_buf = Trans->uac[branch].request.buffer;
        invite_len = Trans->uac[branch].request.buffer_len;
 
-       if (!invite_buf || !invite_len) {
+       if (!invite_buf || invite_len<=0) {
                LM_ERR("INVITE is missing\n");
                goto error;
        }
index ece23bb..b645f3c 100644 (file)
@@ -488,12 +488,16 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
        rb->rbtype=code;
 
        trans->uas.status = code;
+       if(len<=0) {
+               LM_ERR("invalid new buffer len\n");
+               goto error3;
+       }
        buf_len = rb->buffer ? len : len + REPLY_OVERBUFFER_LEN;
        rb->buffer = (char*)shm_resize( rb->buffer, buf_len );
        /* puts the reply's buffer to uas.response */
        if (! rb->buffer ) {
-                       LM_ERR("cannot allocate shmem buffer\n");
-                       goto error3;
+               LM_ERR("cannot allocate shmem buffer\n");
+               goto error3;
        }
        update_local_tags(trans, bm, rb->buffer, buf);
 
@@ -2024,6 +2028,10 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
                 *   larger messages are likely to follow and we will be
                 *   able to reuse the memory frag
                */
+               if (res_len<=0) {
+                       LM_ERR("invalid new buffer len\n");
+                       goto error03;
+               }
                uas_rb->buffer = (char*)shm_resize( uas_rb->buffer, res_len +
                        (msg_status<200 ?  REPLY_OVERBUFFER_LEN : 0));
                if (!uas_rb->buffer) {
index faa7e0d..ec250a8 100644 (file)
@@ -522,7 +522,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 
        buf = build_uac_req(uac_r->method, uac_r->headers, uac_r->body, uac_r->dialog, 0, new_cell,
                &buf_len, &dst);
-       if (!buf) {
+       if (!buf || buf_len<=0) {
                LM_ERR("Error while building message\n");
                ret=E_OUT_OF_MEM;
                goto error1;
@@ -782,19 +782,23 @@ struct retr_buf *local_ack_rb(sip_msg_t *rpl_2xx, struct cell *trans,
        struct dest_info dst;
 
        buf_len = (unsigned)sizeof(struct retr_buf);
-       if (! (buffer = build_dlg_ack(rpl_2xx, trans, branch, hdrs, body,
-                       &buf_len, &dst))) {
+       buffer = build_dlg_ack(rpl_2xx, trans, branch, hdrs, body,
+                       &buf_len, &dst);
+       if (!buffer || buf_len<=0) {
+               if(buffer) {
+                       shm_free(buffer);
+               }
                return 0;
-       } else {
-               /* 'buffer' now points into a contiguous chunk of memory with enough
-                * room to hold both the retr. buffer and the string raw buffer: it
-                * points to the begining of the string buffer; we iterate back to get
-                * the begining of the space for the retr. buffer. */
-               lack = &((struct retr_buf *)buffer)[-1];
-               lack->buffer = buffer;
-               lack->buffer_len = buf_len;
-               lack->dst = dst;
        }
+       /* 'buffer' now points into a contiguous chunk of memory with enough
+        * room to hold both the retr. buffer and the string raw buffer: it
+        * points to the begining of the string buffer; we iterate back to get
+        * the begining of the space for the retr. buffer. */
+       lack = &((struct retr_buf *)buffer)[-1];
+       lack->buffer = buffer;
+       lack->buffer_len = buf_len;
+       lack->dst = dst;
+
 
        /* TODO: need next 2? */
        lack->rbtype = TYPE_LOCAL_ACK;