Skip to content

Commit

Permalink
drouting: Fix an SHM leak with "acc_call_params_avp"
Browse files Browse the repository at this point in the history
Do NOT store an SHM pointer into an AVP, as you have a minimal chance of
somehow getting invoked so you can properly free it!  The solution is to
store the entire struct into the AVP, as a (char *) buffer -- the tm
module will properly free the whole AVP (including this buffer)
afterwards.

Thanks to Răzvan for the tip!
  • Loading branch information
liviuchircu committed Feb 26, 2020
1 parent 46e55b9 commit 4ffe536
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 18 deletions.
28 changes: 11 additions & 17 deletions modules/drouting/drouting.c
Expand Up @@ -2409,7 +2409,7 @@ static int use_next_gw(struct sip_msg* msg,
/* this shuold not happen, it is a bogus state */
LM_BUG("call params AVP not found\n");
} else {
run_dr_cbs(DRCB_ACC_CALL, *(struct dr_acc_call_params **)val.s.s);
run_dr_cbs(DRCB_ACC_CALL, (struct dr_acc_call_params *)val.s.s);
destroy_avp(avp_sk);
}

Expand Down Expand Up @@ -2675,7 +2675,7 @@ inline static int push_gw_for_usage(struct sip_msg *msg,
str *c_attrs = NULL;
int_str val;
int_str dst_id_acc;
struct dr_acc_call_params acp, *pacp;
struct dr_acc_call_params acp;

if (rt) { /* rule based routing, e.g. do_routing() */
if (cr_id == -1) { /* it is not a carrier */
Expand Down Expand Up @@ -2748,23 +2748,17 @@ inline static int push_gw_for_usage(struct sip_msg *msg,
}

if (rt) {
/* save callback parameters */
pacp = shm_malloc(sizeof *pacp);
if (!pacp) {
LM_ERR("oom\n");
goto error;
}
memset(pacp, 0, sizeof *pacp);
memset(&acp, 0, sizeof acp);

pacp->rule = (void*)rt->qr_handler;
pacp->cr_id = cr_id;
pacp->gw_id = gw_id;
pacp->msg = msg;
acp.rule = (void *)rt->qr_handler;
acp.cr_id = cr_id;
acp.gw_id = gw_id;
acp.msg = msg;

dst_id_acc.s.s = (char *)&pacp;
dst_id_acc.s.len = sizeof(void *);
if (add_avp_last(AVP_VAL_STR, current_partition->acc_call_params_avp,
dst_id_acc)) {
dst_id_acc.s.s = (char *)&acp;
dst_id_acc.s.len = sizeof acp;
if (add_avp_last(AVP_VAL_STR,
current_partition->acc_call_params_avp, dst_id_acc)) {
LM_ERR("failed to insert dst_id avp\n");
goto error;
}
Expand Down
2 changes: 1 addition & 1 deletion usr_avp.c
Expand Up @@ -125,7 +125,7 @@ struct usr_avp* new_avp(unsigned short flags, int id, int_str val)

if (flags & AVP_VAL_STR) {
/* avp type ID, str value */
s = (str*)(void*)&(avp->data);
s = (str *)&avp->data;
s->len = val.s.len;
s->s = (char*)s + sizeof(str);
memcpy( s->s, val.s.s , s->len);
Expand Down

0 comments on commit 4ffe536

Please sign in to comment.