2
0
Эх сурвалжийг харах

tm: safety checks for branch request len

(cherry picked from commit c45913497f222c67bcccdbc8724b25bb083c556f)
(cherry picked from commit 4f9f7160511a5f9301e2fb5764d857f58eb8f95b)
Daniel-Constantin Mierla 5 жил өмнө
parent
commit
41359f55bc

+ 11 - 3
src/modules/tm/t_cancel.c

@@ -304,8 +304,12 @@ int cancel_branch( struct cell *t, int branch,
 	#endif /* CANCEL_REASON_SUPPORT */
 								);
 	}
-	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);
@@ -511,8 +515,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;

+ 15 - 3
src/modules/tm/t_fwd.c

@@ -476,8 +476,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;
 	}
@@ -885,7 +889,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;
 	}
@@ -1113,7 +1121,11 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
 				, 0
 #endif /* CANCEL_REASON_SUPPORT */
 				);
-		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;

+ 2 - 2
src/modules/tm/t_msgbuilder.c

@@ -261,7 +261,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
 #ifdef CANCEL_REASON_SUPPORT
 	, struct cancel_reason *reason
@@ -285,7 +285,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;
 	}

+ 10 - 2
src/modules/tm/t_reply.c

@@ -486,12 +486,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);
 
@@ -1951,6 +1955,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) {

+ 16 - 12
src/modules/tm/uac.c

@@ -505,7 +505,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;
@@ -754,19 +754,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;