Mercurial > hg > freeDiameter
comparison libfdproto/messages.c @ 1298:0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Tue, 23 Jun 2015 12:12:10 +0800 |
parents | c9a160b815ea |
children | 3f1e79e1273e |
comparison
equal
deleted
inserted
replaced
1297:2fbee0e39c04 | 1298:0f215b0dda5e |
---|---|
229 init_avp(new); | 229 init_avp(new); |
230 | 230 |
231 if (model) { | 231 if (model) { |
232 struct dict_avp_data dictdata; | 232 struct dict_avp_data dictdata; |
233 | 233 |
234 CHECK_FCT( fd_dict_getval(model, &dictdata) ); | 234 CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } ); |
235 | 235 |
236 new->avp_model = model; | 236 new->avp_model = model; |
237 new->avp_public.avp_code = dictdata.avp_code; | 237 new->avp_public.avp_code = dictdata.avp_code; |
238 new->avp_public.avp_flags = dictdata.avp_flag_val; | 238 new->avp_public.avp_flags = dictdata.avp_flag_val; |
239 new->avp_public.avp_len = GETINITIALSIZE(dictdata.avp_basetype, dictdata.avp_flag_val ); | 239 new->avp_public.avp_len = GETINITIALSIZE(dictdata.avp_basetype, dictdata.avp_flag_val ); |
245 } | 245 } |
246 | 246 |
247 if (flags & AVPFL_SET_RAWDATA_FROM_AVP) { | 247 if (flags & AVPFL_SET_RAWDATA_FROM_AVP) { |
248 new->avp_rawlen = (*avp)->avp_public.avp_len - GETAVPHDRSZ( (*avp)->avp_public.avp_flags ); | 248 new->avp_rawlen = (*avp)->avp_public.avp_len - GETAVPHDRSZ( (*avp)->avp_public.avp_flags ); |
249 if (new->avp_rawlen) { | 249 if (new->avp_rawlen) { |
250 CHECK_MALLOC( new->avp_rawdata = malloc(new->avp_rawlen) ); | 250 CHECK_MALLOC_DO( new->avp_rawdata = malloc(new->avp_rawlen), { free(new); return __ret__; } ); |
251 memset(new->avp_rawdata, 0x00, new->avp_rawlen); | 251 memset(new->avp_rawdata, 0x00, new->avp_rawlen); |
252 } | 252 } |
253 } | 253 } |
254 | 254 |
255 /* The new object is ready, return */ | 255 /* The new object is ready, return */ |
283 if (model) { | 283 if (model) { |
284 struct dictionary *dict; | 284 struct dictionary *dict; |
285 struct dict_cmd_data dictdata; | 285 struct dict_cmd_data dictdata; |
286 struct dict_object *dictappl; | 286 struct dict_object *dictappl; |
287 | 287 |
288 CHECK_FCT( fd_dict_getdict(model, &dict) ); | 288 CHECK_FCT_DO( fd_dict_getdict(model, &dict), { free(new); return __ret__; } ); |
289 CHECK_FCT( fd_dict_getval(model, &dictdata) ); | 289 CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } ); |
290 | 290 |
291 new->msg_model = model; | 291 new->msg_model = model; |
292 new->msg_public.msg_flags = dictdata.cmd_flag_val; | 292 new->msg_public.msg_flags = dictdata.cmd_flag_val; |
293 new->msg_public.msg_code = dictdata.cmd_code; | 293 new->msg_public.msg_code = dictdata.cmd_code; |
294 | 294 |
295 /* Initialize application from the parent, if any */ | 295 /* Initialize application from the parent, if any */ |
296 CHECK_FCT( fd_dict_search( dict, DICT_APPLICATION, APPLICATION_OF_COMMAND, model, &dictappl, 0) ); | 296 CHECK_FCT_DO( fd_dict_search( dict, DICT_APPLICATION, APPLICATION_OF_COMMAND, model, &dictappl, 0), { free(new); return __ret__; } ); |
297 if (dictappl != NULL) { | 297 if (dictappl != NULL) { |
298 struct dict_application_data appdata; | 298 struct dict_application_data appdata; |
299 CHECK_FCT( fd_dict_getval(dictappl, &appdata) ); | 299 CHECK_FCT_DO( fd_dict_getval(dictappl, &appdata), { free(new); return __ret__; } ); |
300 new->msg_public.msg_appl = appdata.application_id; | 300 new->msg_public.msg_appl = appdata.application_id; |
301 } | 301 } |
302 } | 302 } |
303 | 303 |
304 if (flags & MSGFL_ALLOC_ETEID) { | 304 if (flags & MSGFL_ALLOC_ETEID) { |
362 size_t sidlen; | 362 size_t sidlen; |
363 struct avp * avp; | 363 struct avp * avp; |
364 union avp_value val; | 364 union avp_value val; |
365 | 365 |
366 if (!sess_id_avp) { | 366 if (!sess_id_avp) { |
367 CHECK_FCT( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT) ); | 367 CHECK_FCT_DO( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT), { free(ans); return __ret__; } ); |
368 } | 368 } |
369 CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ) ); | 369 CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), { free(ans); return __ret__; } ); |
370 CHECK_FCT( fd_msg_avp_new ( sess_id_avp, 0, &avp ) ); | 370 CHECK_FCT_DO( fd_msg_avp_new ( sess_id_avp, 0, &avp ), { free(ans); return __ret__; } ); |
371 val.os.data = sid; | 371 val.os.data = sid; |
372 val.os.len = sidlen; | 372 val.os.len = sidlen; |
373 CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); | 373 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), { free(avp); free(ans); return __ret__; } ); |
374 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_FIRST_CHILD, avp ) ); | 374 CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_FIRST_CHILD, avp ), { free(avp); free(ans); return __ret__; } ); |
375 ans->msg_sess = sess; | 375 ans->msg_sess = sess; |
376 CHECK_FCT( fd_sess_ref_msg(sess) ); | 376 CHECK_FCT_DO( fd_sess_ref_msg(sess), { free(ans); return __ret__; } ); |
377 } | 377 } |
378 | 378 |
379 /* Add all Proxy-Info AVPs from the query if any */ | 379 /* Add all Proxy-Info AVPs from the query if any */ |
380 if (! (flags & MSGFL_ANSW_NOPROXYINFO)) { | 380 if (! (flags & MSGFL_ANSW_NOPROXYINFO)) { |
381 struct avp * avp; | 381 struct avp * avp; |
382 struct fd_pei pei; | 382 struct fd_pei pei; |
383 struct fd_list avpcpylist = FD_LIST_INITIALIZER(avpcpylist); | 383 struct fd_list avpcpylist = FD_LIST_INITIALIZER(avpcpylist); |
384 | 384 |
385 CHECK_FCT( fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL) ); | 385 CHECK_FCT_DO( fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL) , { free(ans); return __ret__; } ); |
386 while (avp) { | 386 while (avp) { |
387 if ( (avp->avp_public.avp_code == AC_PROXY_INFO) | 387 if ( (avp->avp_public.avp_code == AC_PROXY_INFO) |
388 && (avp->avp_public.avp_vendor == 0) ) { | 388 && (avp->avp_public.avp_vendor == 0) ) { |
389 /* We found a Proxy-Info, need to duplicate it in the answer */ | 389 /* We found a Proxy-Info, need to duplicate it in the answer */ |
390 | 390 |
391 /* In order to avoid dealing with all different possibilities of states, we just create a buffer then parse it */ | 391 /* In order to avoid dealing with all different possibilities of states, we just create a buffer then parse it */ |
392 unsigned char * buf = NULL; | 392 unsigned char * buf = NULL; |
393 size_t offset = 0; | 393 size_t offset = 0; |
394 | 394 |
395 /* Create a buffer with the content of the AVP. This is easier than going through the list */ | 395 /* Create a buffer with the content of the AVP. This is easier than going through the list */ |
396 CHECK_FCT( fd_msg_update_length(avp) ); | 396 CHECK_FCT_DO( fd_msg_update_length(avp), { free(ans); return __ret__; } ); |
397 CHECK_MALLOC( buf = malloc(avp->avp_public.avp_len) ); | 397 CHECK_MALLOC_DO( buf = malloc(avp->avp_public.avp_len), { free(ans); return __ret__; } ); |
398 CHECK_FCT( bufferize_avp(buf, avp->avp_public.avp_len, &offset, avp) ); | 398 CHECK_FCT_DO( bufferize_avp(buf, avp->avp_public.avp_len, &offset, avp), { free(buf); free(ans); return __ret__; } ); |
399 | 399 |
400 /* Now we parse this buffer to create a copy AVP */ | 400 /* Now we parse this buffer to create a copy AVP */ |
401 CHECK_FCT( parsebuf_list(buf, avp->avp_public.avp_len, &avpcpylist) ); | 401 CHECK_FCT_DO( parsebuf_list(buf, avp->avp_public.avp_len, &avpcpylist), { free(buf); free(ans); return __ret__; } ); |
402 | 402 |
403 /* Parse dictionary objects now to remove the dependency on the buffer */ | 403 /* Parse dictionary objects now to remove the dependency on the buffer */ |
404 CHECK_FCT( parsedict_do_chain(dict, &avpcpylist, 0, &pei) ); | 404 CHECK_FCT_DO( parsedict_do_chain(dict, &avpcpylist, 0, &pei), { /* leaking the avpcpylist -- this should never happen anyway */ free(buf); free(ans); return __ret__; } ); |
405 | 405 |
406 /* Done for this AVP */ | 406 /* Done for this AVP */ |
407 free(buf); | 407 free(buf); |
408 | 408 |
409 /* We move this AVP now so that we do not parse again in next loop */ | 409 /* We move this AVP now so that we do not parse again in next loop */ |
410 fd_list_move_end(&ans->msg_chain.children, &avpcpylist); | 410 fd_list_move_end(&ans->msg_chain.children, &avpcpylist); |
411 } | 411 } |
412 /* move to next AVP in the message, we can have several Proxy-Info instances */ | 412 /* move to next AVP in the message, we can have several Proxy-Info instances */ |
413 CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); | 413 CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), { free(ans); return __ret__; } ); |
414 } | 414 } |
415 } | 415 } |
416 | 416 |
417 /* associate with query */ | 417 /* associate with query */ |
418 ans->msg_query = qry; | 418 ans->msg_query = qry; |