Browse code

siptrace: fix pkg memory leak when module configured with core callbacks

- Correctly freeng pkg memory in core callbacks when body modifications take place with X-Siptrace headers,
also fix potential pkg_free with not dynamicaly allocated objects.

Dennis Yurasov authored on 21/03/2022 13:23:36 • Daniel-Constantin Mierla committed on 22/03/2022 07:24:47
Showing 3 changed files
... ...
@@ -2118,6 +2118,8 @@ int siptrace_net_data_recv(sr_event_param_t *evp)
2118 2118
 	sr_net_info_t *nd;
2119 2119
 	siptrace_data_t sto;
2120 2120
 	sip_msg_t tmsg;
2121
+	int evcb_ret;
2122
+	int ret = 0;
2121 2123
 
2122 2124
 	if(evp->data == 0)
2123 2125
 		return -1;
... ...
@@ -2160,10 +2162,15 @@ int siptrace_net_data_recv(sr_event_param_t *evp)
2160 2162
 
2161 2163
 	sto.dir = "in";
2162 2164
 
2163
-	if(siptrace_exec_evcb_msg(&sto) == DROP_R_F) {
2165
+	evcb_ret=siptrace_exec_evcb_msg(&sto);
2166
+	if(evcb_ret < 0) {
2167
+		ret = -1;
2168
+		goto finish;
2169
+	}
2170
+	if(evcb_ret == DROP_R_F) {
2164 2171
 		/* drop() used in event_route - all done */
2165 2172
 		LM_DBG("skipping processing message due to drop\n");
2166
-		return 0;
2173
+		goto finish;
2167 2174
 	}
2168 2175
 
2169 2176
 	LM_DBG("processing message mode %d\n", _siptrace_mode);
... ...
@@ -2223,7 +2230,11 @@ afterdb:
2223 2230
 		trace_send_duplicate(sto.body.s, sto.body.len, NULL);
2224 2231
 	}
2225 2232
 
2226
-	return 0;
2233
+finish:
2234
+	if(sip_trace_xheaders_free(&sto) != 0)
2235
+		return -1;
2236
+
2237
+	return ret;
2227 2238
 }
2228 2239
 
2229 2240
 /**
... ...
@@ -2236,6 +2247,8 @@ int siptrace_net_data_sent(sr_event_param_t *evp)
2236 2247
 	siptrace_data_t sto;
2237 2248
 	sip_msg_t tmsg;
2238 2249
 	int proto;
2250
+	int evcb_ret;
2251
+	int ret = 0;
2239 2252
 
2240 2253
 	if(evp->data == 0)
2241 2254
 		return -1;
... ...
@@ -2268,7 +2281,7 @@ int siptrace_net_data_sent(sr_event_param_t *evp)
2268 2281
 		if(new_dst.send_sock->sock_str.len>=SIPTRACE_ADDR_MAX-1) {
2269 2282
 			LM_ERR("socket string is too large: %d\n",
2270 2283
 					new_dst.send_sock->sock_str.len);
2271
-			goto error;
2284
+			return -1;
2272 2285
 		}
2273 2286
 		strncpy(sto.fromip_buff, new_dst.send_sock->sock_str.s,
2274 2287
 				new_dst.send_sock->sock_str.len);
... ...
@@ -2291,10 +2304,15 @@ int siptrace_net_data_sent(sr_event_param_t *evp)
2291 2304
 
2292 2305
 	sto.dir = "out";
2293 2306
 
2294
-	if(siptrace_exec_evcb_msg(&sto) == DROP_R_F) {
2307
+	evcb_ret=siptrace_exec_evcb_msg(&sto);
2308
+	if(evcb_ret < 0) {
2309
+		ret = -1;
2310
+		goto finish;
2311
+	}
2312
+	if(evcb_ret == DROP_R_F) {
2295 2313
 		/* drop() used in event_route - all done */
2296 2314
 		LM_DBG("skipping processing message due to drop\n");
2297
-		return 0;
2315
+		goto finish;
2298 2316
 	}
2299 2317
 
2300 2318
 	LM_DBG("processing message mode %d\n", _siptrace_mode);
... ...
@@ -2353,11 +2371,11 @@ afterdb:
2353 2371
 	if(_siptrace_mode & SIPTRACE_MODE_URI) {
2354 2372
 		trace_send_duplicate(sto.body.s, sto.body.len, NULL);
2355 2373
 	}
2374
+finish:
2375
+	if(sip_trace_xheaders_free(&sto) != 0)
2376
+		return -1;
2356 2377
 
2357
-	return 0;
2358
-
2359
-error:
2360
-	return -1;
2378
+	return ret;
2361 2379
 }
2362 2380
 
2363 2381
 /**
... ...
@@ -40,6 +40,7 @@ typedef struct _siptrace_data
40 40
 	int_str avp_value;
41 41
 	struct search_state state;
42 42
 	str body;
43
+	int alloc_body;
43 44
 	str callid;
44 45
 	str method;
45 46
 	str status;
... ...
@@ -48,6 +49,7 @@ typedef struct _siptrace_data
48 49
 	str fromip;
49 50
 	str totag;
50 51
 	str toip;
52
+	int alloc_headers;
51 53
 	char toip_buff[SIPTRACE_ADDR_MAX];
52 54
 	char fromip_buff[SIPTRACE_ADDR_MAX];
53 55
 	struct timeval tv;
... ...
@@ -139,6 +139,7 @@ int sip_trace_xheaders_write(struct _siptrace_data *sto)
139 139
 	// Change sto to point to the new buffer.
140 140
 	sto->body.s = buf;
141 141
 	sto->body.len += bytes_written;
142
+	sto->alloc_body = 1;
142 143
 	return 0;
143 144
 error:
144 145
 	if(buf != NULL) {
... ...
@@ -224,6 +225,7 @@ int sip_trace_xheaders_read(struct _siptrace_data *sto)
224 225
 	*eoh = '\r';
225 226
 	memmove(xheaders, eoh, sto->body.len - (eoh - sto->body.s));
226 227
 	sto->body.len -= eoh - xheaders;
228
+	sto->alloc_headers = 1;
227 229
 
228 230
 	return 0;
229 231
 
... ...
@@ -252,14 +254,15 @@ erroraftermalloc:
252 254
  */
253 255
 int sip_trace_xheaders_free(struct _siptrace_data *sto)
254 256
 {
255
-	if(trace_xheaders_write != 0) {
257
+	if(sto->alloc_body != 0) {
256 258
 		if(sto->body.s) {
257 259
 			pkg_free(sto->body.s);
258 260
 			sto->body.s = 0;
259 261
 		}
262
+		sto->alloc_body = 0;
260 263
 	}
261 264
 
262
-	if(trace_xheaders_read != 0) {
265
+	if(sto->alloc_headers != 0) {
263 266
 		if(sto->fromip.s) {
264 267
 			pkg_free(sto->fromip.s);
265 268
 			sto->fromip.s = 0;
... ...
@@ -272,6 +275,7 @@ int sip_trace_xheaders_free(struct _siptrace_data *sto)
272 275
 			pkg_free(sto->dir);
273 276
 			sto->dir = 0;
274 277
 		}
278
+		sto->alloc_headers = 0;
275 279
 	}
276 280
 
277 281
 	return 0;