Переглянути джерело

bug_fix: checking of return value of snprintf aligned to C99

Jiri Kuthan 22 роки тому
батько
коміт
0bf716b854
5 змінених файлів з 34 додано та 20 видалено
  1. 7 1
      main.c
  2. 4 4
      modules/tm/t_msgbuilder.c
  3. 3 3
      modules/tm/uac.c
  4. 16 12
      msg_translator.c
  5. 4 0
      msg_translator.h

+ 7 - 1
main.c

@@ -1374,7 +1374,13 @@ try_again:
 		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
 		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
 									(unsigned short) sock_info[r].port_no);
-		if (port_no_str_len<0){
+		/* if buffer too small, snprintf may return per C99 estimated size
+		   of needed space; there is no guarantee how many characters 
+		   have been written to the buffer and we can be happy if
+		   the snprintf implementation zero-terminates whatever it wrote
+		   -jku
+		*/
+		if (port_no_str_len<0 || port_no_str_len>=MAX_PORT_LEN){
 			fprintf(stderr, "ERROR: bad port number: %d\n", 
 						sock_info[r].port_no);
 			goto error;

+ 4 - 4
modules/tm/t_msgbuilder.c

@@ -196,7 +196,7 @@ char *build_uac_request(  str msg_type, str dst, str from,
 	content_len_len=snprintf(
 		content_len, sizeof(content_len), 
 		"%d", body.len );
-	if (content_len_len==-1) {
+	if (content_len_len==-1 || content_len_len>=sizeof(content_len)) {
 		LOG(L_ERR, "ERROR: uac: content_len too big\n");
 		return 0;
 	}
@@ -204,7 +204,7 @@ char *build_uac_request(  str msg_type, str dst, str from,
 	cseq_str_len=snprintf( 
 		cseq_str, sizeof(cseq_str),
 		"%d", cseq );
-	if (cseq_str_len==-1) {
+	if (cseq_str_len==-1 || cseq_str_len>=sizeof(cseq_str)) {
 		LOG(L_ERR, "ERROR: uac: cseq too big\n");
 		return 0;
 	}
@@ -343,7 +343,7 @@ char *build_uac_request_dlg(str* msg,           /* Method */
 	      */
 	if (body) {
 		content_len_len = snprintf(content_len, sizeof(content_len), "%d", body->len);
-		if (content_len_len == -1) {
+		if (content_len_len == -1 || content_len_len>=sizeof(content_len)) {
 			LOG(L_ERR, "ERROR: build_uac_request_dlg: content_len too big\n");
 			return 0;
 		}
@@ -353,7 +353,7 @@ char *build_uac_request_dlg(str* msg,           /* Method */
 	      * Print CSeq 
 	      */
 	cseq_str_len = snprintf(cseq_str, sizeof(cseq_str), "%d", cseq);
-	if (cseq_str_len == -1) {
+	if (cseq_str_len == -1 || cseq_str_len >= sizeof(cseq_str)) {
 		LOG(L_ERR, "ERROR: build_uac_request_dlg: cseq too big\n");
 		return 0;
 	}

+ 3 - 3
modules/tm/uac.c

@@ -160,7 +160,7 @@ int uac_child_init( int rank )
 			"%c%d@%.*s", CID_SEP, my_pid(), 
 			sock_info[bind_idx].address_str.len,
 			sock_info[bind_idx].address_str.s );
-	if (callid_suffix_len==-1) {
+	if (callid_suffix_len==-1 || callid_suffix_len>=CALLID_SUFFIX_LEN) {
 		LOG(L_ERR, "ERROR: uac_child_init: buffer too small\n");
 		return -1;
 	}
@@ -214,7 +214,7 @@ int t_uac( str *msg_type, str *dst,
 	/* generate_callid(); */
 	callid_nr++;
 	r=snprintf(callid, rand_len+1, "%0*lx", rand_len, callid_nr );
-	if (r==-1) {
+	if (r==-1 || r>=rand_len+1) {
 		LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
 		goto error00;
 	}
@@ -356,7 +356,7 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 	if (cid == 0) {
 		callid_nr++;
 		r = snprintf(callid, rand_len + 1, "%0*lx", rand_len, callid_nr);
-		if (r == -1) {
+		if (r == -1 || r>=rand_len+1) {
 			LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
 			goto error00;
 		}

+ 16 - 12
msg_translator.c

@@ -24,6 +24,12 @@
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ *
+ * History:
+ * --------
+ * 2003-01-20 bug_fix: use of return value of snprintf aligned to C99 (jiri)
+ *
  */
 
 
@@ -118,7 +124,7 @@ int check_address(struct ip_addr* ip, char *name, int resolver)
 }
 
 
-char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
+static char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
 {
 	static char buf[MAX_WARNING_LEN];
 	static unsigned int fix_len=0;
@@ -127,16 +133,16 @@ char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
 
 	if (!fix_len)
 	{
-		memcpy(buf+fix_len,"Warning: 392 ",13);
-		fix_len +=13;
+		memcpy(buf+fix_len,WARNING, WARNING_LEN);
+		fix_len +=WARNING_LEN;
 		memcpy(buf+fix_len, bind_address->name.s,bind_address->name.len);
 		fix_len += bind_address->name.len;
 		//*(buf+fix_len++) = ':';
 		memcpy(buf+fix_len,bind_address->port_no_str.s,
 			bind_address->port_no_str.len);
 		fix_len += bind_address->port_no_str.len;
-		memcpy(buf+fix_len, " \"Noisy feedback tells: ",24);
-		fix_len += 24;
+		memcpy(buf+fix_len, WARNING_PHRASE,WARNING_PHRASE_LEN);
+		fix_len += WARNING_PHRASE_LEN;
 	}
 
 	/*adding out_uri*/
@@ -153,7 +159,8 @@ char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
 		msg->parsed_flag & HDR_EOH ? '=' : '>', /* should be = */
 		via_cnt );
 
-	if (print_len==-1) {
+	if (print_len==-1 || print_len>=MAX_WARNING_LEN-fix_len) {
+		LOG(L_ERR, "ERROR: warning_builder: buffer size exceeded\n");
 		*returned_len=0;
 		return 0;
 	} else {
@@ -661,11 +668,8 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 	}
 	if (sip_warning) {
 		warning = warning_builder(msg,&warning_len);
-		if (warning==0) {
-			LOG(L_ERR, "ERROR: warning too big\n");
-			goto error01;
-		}
-		len += warning_len + CRLF_LEN;
+		if (warning) len += warning_len + CRLF_LEN;
+		else LOG(L_WARN, "WARNING: warning skipped -- too big\n");
 	}
 	/* end of message */
 	len += CRLF_LEN; /*new line*/
@@ -752,7 +756,7 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
 		memcpy( p, CRLF, CRLF_LEN );
 		p+=CRLF_LEN;
 	}
-	if (sip_warning) {
+	if (sip_warning && warning) {
 		memcpy( p, warning, warning_len);
 		p+=warning_len;
 		memcpy( p, CRLF, CRLF_LEN);

+ 4 - 0
msg_translator.h

@@ -33,6 +33,10 @@
 #define MY_HF_SEP_LEN 2
 
 #define BRANCH_SEPARATOR '.'
+#define WARNING "Warning: 392 "
+#define WARNING_LEN (sizeof(WARNING)-1)
+#define WARNING_PHRASE " \"Noisy feedback tells: "
+#define WARNING_PHRASE_LEN (sizeof(WARNING_PHRASE)-1)
 
 #include "parser/msg_parser.h"
 #include "ip_addr.h"