Browse code

bug_fix: checking of return value of snprintf aligned to C99

Jiri Kuthan authored on 20/01/2003 01:18:50
Showing 5 changed files
... ...
@@ -1374,7 +1374,13 @@ try_again:
1374 1374
 		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
1375 1375
 		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
1376 1376
 									(unsigned short) sock_info[r].port_no);
1377
-		if (port_no_str_len<0){
1377
+		/* if buffer too small, snprintf may return per C99 estimated size
1378
+		   of needed space; there is no guarantee how many characters 
1379
+		   have been written to the buffer and we can be happy if
1380
+		   the snprintf implementation zero-terminates whatever it wrote
1381
+		   -jku
1382
+		*/
1383
+		if (port_no_str_len<0 || port_no_str_len>=MAX_PORT_LEN){
1378 1384
 			fprintf(stderr, "ERROR: bad port number: %d\n", 
1379 1385
 						sock_info[r].port_no);
1380 1386
 			goto error;
... ...
@@ -196,7 +196,7 @@ char *build_uac_request(  str msg_type, str dst, str from,
196 196
 	content_len_len=snprintf(
197 197
 		content_len, sizeof(content_len), 
198 198
 		"%d", body.len );
199
-	if (content_len_len==-1) {
199
+	if (content_len_len==-1 || content_len_len>=sizeof(content_len)) {
200 200
 		LOG(L_ERR, "ERROR: uac: content_len too big\n");
201 201
 		return 0;
202 202
 	}
... ...
@@ -204,7 +204,7 @@ char *build_uac_request(  str msg_type, str dst, str from,
204 204
 	cseq_str_len=snprintf( 
205 205
 		cseq_str, sizeof(cseq_str),
206 206
 		"%d", cseq );
207
-	if (cseq_str_len==-1) {
207
+	if (cseq_str_len==-1 || cseq_str_len>=sizeof(cseq_str)) {
208 208
 		LOG(L_ERR, "ERROR: uac: cseq too big\n");
209 209
 		return 0;
210 210
 	}
... ...
@@ -343,7 +343,7 @@ char *build_uac_request_dlg(str* msg,           /* Method */
343 343
 	      */
344 344
 	if (body) {
345 345
 		content_len_len = snprintf(content_len, sizeof(content_len), "%d", body->len);
346
-		if (content_len_len == -1) {
346
+		if (content_len_len == -1 || content_len_len>=sizeof(content_len)) {
347 347
 			LOG(L_ERR, "ERROR: build_uac_request_dlg: content_len too big\n");
348 348
 			return 0;
349 349
 		}
... ...
@@ -353,7 +353,7 @@ char *build_uac_request_dlg(str* msg,           /* Method */
353 353
 	      * Print CSeq 
354 354
 	      */
355 355
 	cseq_str_len = snprintf(cseq_str, sizeof(cseq_str), "%d", cseq);
356
-	if (cseq_str_len == -1) {
356
+	if (cseq_str_len == -1 || cseq_str_len >= sizeof(cseq_str)) {
357 357
 		LOG(L_ERR, "ERROR: build_uac_request_dlg: cseq too big\n");
358 358
 		return 0;
359 359
 	}
... ...
@@ -160,7 +160,7 @@ int uac_child_init( int rank )
160 160
 			"%c%d@%.*s", CID_SEP, my_pid(), 
161 161
 			sock_info[bind_idx].address_str.len,
162 162
 			sock_info[bind_idx].address_str.s );
163
-	if (callid_suffix_len==-1) {
163
+	if (callid_suffix_len==-1 || callid_suffix_len>=CALLID_SUFFIX_LEN) {
164 164
 		LOG(L_ERR, "ERROR: uac_child_init: buffer too small\n");
165 165
 		return -1;
166 166
 	}
... ...
@@ -214,7 +214,7 @@ int t_uac( str *msg_type, str *dst,
214 214
 	/* generate_callid(); */
215 215
 	callid_nr++;
216 216
 	r=snprintf(callid, rand_len+1, "%0*lx", rand_len, callid_nr );
217
-	if (r==-1) {
217
+	if (r==-1 || r>=rand_len+1) {
218 218
 		LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
219 219
 		goto error00;
220 220
 	}
... ...
@@ -356,7 +356,7 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
356 356
 	if (cid == 0) {
357 357
 		callid_nr++;
358 358
 		r = snprintf(callid, rand_len + 1, "%0*lx", rand_len, callid_nr);
359
-		if (r == -1) {
359
+		if (r == -1 || r>=rand_len+1) {
360 360
 			LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
361 361
 			goto error00;
362 362
 		}
... ...
@@ -24,6 +24,12 @@
24 24
  * You should have received a copy of the GNU General Public License 
25 25
  * along with this program; if not, write to the Free Software 
26 26
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ * 
28
+ *
29
+ * History:
30
+ * --------
31
+ * 2003-01-20 bug_fix: use of return value of snprintf aligned to C99 (jiri)
32
+ *
27 33
  */
28 34
 
29 35
 
... ...
@@ -118,7 +124,7 @@ int check_address(struct ip_addr* ip, char *name, int resolver)
118 118
 }
119 119
 
120 120
 
121
-char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
121
+static char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
122 122
 {
123 123
 	static char buf[MAX_WARNING_LEN];
124 124
 	static unsigned int fix_len=0;
... ...
@@ -127,16 +133,16 @@ char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
127 127
 
128 128
 	if (!fix_len)
129 129
 	{
130
-		memcpy(buf+fix_len,"Warning: 392 ",13);
131
-		fix_len +=13;
130
+		memcpy(buf+fix_len,WARNING, WARNING_LEN);
131
+		fix_len +=WARNING_LEN;
132 132
 		memcpy(buf+fix_len, bind_address->name.s,bind_address->name.len);
133 133
 		fix_len += bind_address->name.len;
134 134
 		//*(buf+fix_len++) = ':';
135 135
 		memcpy(buf+fix_len,bind_address->port_no_str.s,
136 136
 			bind_address->port_no_str.len);
137 137
 		fix_len += bind_address->port_no_str.len;
138
-		memcpy(buf+fix_len, " \"Noisy feedback tells: ",24);
139
-		fix_len += 24;
138
+		memcpy(buf+fix_len, WARNING_PHRASE,WARNING_PHRASE_LEN);
139
+		fix_len += WARNING_PHRASE_LEN;
140 140
 	}
141 141
 
142 142
 	/*adding out_uri*/
... ...
@@ -153,7 +159,8 @@ char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
153 153
 		msg->parsed_flag & HDR_EOH ? '=' : '>', /* should be = */
154 154
 		via_cnt );
155 155
 
156
-	if (print_len==-1) {
156
+	if (print_len==-1 || print_len>=MAX_WARNING_LEN-fix_len) {
157
+		LOG(L_ERR, "ERROR: warning_builder: buffer size exceeded\n");
157 158
 		*returned_len=0;
158 159
 		return 0;
159 160
 	} else {
... ...
@@ -661,11 +668,8 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
661 661
 	}
662 662
 	if (sip_warning) {
663 663
 		warning = warning_builder(msg,&warning_len);
664
-		if (warning==0) {
665
-			LOG(L_ERR, "ERROR: warning too big\n");
666
-			goto error01;
667
-		}
668
-		len += warning_len + CRLF_LEN;
664
+		if (warning) len += warning_len + CRLF_LEN;
665
+		else LOG(L_WARN, "WARNING: warning skipped -- too big\n");
669 666
 	}
670 667
 	/* end of message */
671 668
 	len += CRLF_LEN; /*new line*/
... ...
@@ -752,7 +756,7 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
752 752
 		memcpy( p, CRLF, CRLF_LEN );
753 753
 		p+=CRLF_LEN;
754 754
 	}
755
-	if (sip_warning) {
755
+	if (sip_warning && warning) {
756 756
 		memcpy( p, warning, warning_len);
757 757
 		p+=warning_len;
758 758
 		memcpy( p, CRLF, CRLF_LEN);
... ...
@@ -33,6 +33,10 @@
33 33
 #define MY_HF_SEP_LEN 2
34 34
 
35 35
 #define BRANCH_SEPARATOR '.'
36
+#define WARNING "Warning: 392 "
37
+#define WARNING_LEN (sizeof(WARNING)-1)
38
+#define WARNING_PHRASE " \"Noisy feedback tells: "
39
+#define WARNING_PHRASE_LEN (sizeof(WARNING_PHRASE)-1)
36 40
 
37 41
 #include "parser/msg_parser.h"
38 42
 #include "ip_addr.h"