Skip to content

Commit ca03e3d

Browse files
committed
tm: Fix rare crashes during SRV failover (part 1)
Fix a specific edge-case where OpenSIPS crashes with double pkg_free(), whenever: - SRV failover is engaged (SRV dest with a 408 or 503 reply from downstream) - a branch route is in use - script developer does a READ and WRITE on the $ru or $du, from this branch route Many thanks to Bogdan Iancu for helping troubleshoot this! (cherry picked from commit 6f78666)
1 parent 579ba99 commit ca03e3d

1 file changed

Lines changed: 13 additions & 33 deletions

File tree

modules/tm/t_msgbuilder.h

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -211,42 +211,29 @@ static inline int fake_req(struct sip_msg *faked_req, struct sip_msg *shm_msg,
211211
faked_req->msg_flags |= FL_TM_FAKE_REQ;
212212

213213
if (uac) {
214-
215-
/* duplicate some values into private mem
216-
* so that they can be visible and changed at script level */
217-
/* RURI / new URI */
218-
faked_req->new_uri.s=pkg_malloc( uac->uri.len+1 );
219-
if (!faked_req->new_uri.s) {
214+
/* duplicate all URI values into private mem
215+
* so they are visible and change-able at script level */
216+
if (pkg_nt_str_dup(&faked_req->new_uri, &uac->uri) != 0) {
220217
LM_ERR("no uri/pkg mem\n");
221218
goto out0;
222219
}
223-
faked_req->new_uri.len = uac->uri.len;
224-
memcpy( faked_req->new_uri.s, uac->uri.s, uac->uri.len);
225-
faked_req->new_uri.s[faked_req->new_uri.len]=0;
226220

227-
/* duplicate the dst_uri and path_vec into private mem
228-
* so that they can be visible and changed at script level */
229221
if (uac->duri.s) {
230-
faked_req->dst_uri.s = pkg_malloc(uac->duri.len);
231-
if (!faked_req->dst_uri.s) {
222+
if (pkg_nt_str_dup(&faked_req->dst_uri, &uac->duri) != 0) {
232223
LM_ERR("out of pkg mem\n");
233224
goto out1;
234225
}
235-
memcpy(faked_req->dst_uri.s, uac->duri.s, uac->duri.len);
236226
} else {
237-
faked_req->dst_uri.s = NULL;
238-
faked_req->dst_uri.len = 0;
227+
faked_req->dst_uri = STR_NULL;
239228
}
229+
240230
if (uac->path_vec.s) {
241-
faked_req->path_vec.s = pkg_malloc(uac->path_vec.len);
242-
if (!faked_req->path_vec.s) {
231+
if (pkg_nt_str_dup(&faked_req->path_vec, &uac->path_vec) != 0) {
243232
LM_ERR("out of pkg mem\n");
244233
goto out2;
245234
}
246-
memcpy(faked_req->path_vec.s, uac->path_vec.s, uac->path_vec.len);
247235
} else {
248-
faked_req->path_vec.s = NULL;
249-
faked_req->path_vec.len = 0;
236+
faked_req->path_vec = STR_NULL;
250237
}
251238

252239
/* set the branch flags from the elected branch */
@@ -257,28 +244,21 @@ static inline int fake_req(struct sip_msg *faked_req, struct sip_msg *shm_msg,
257244
/* duplicate advertised address and port from UAC into
258245
* private mem so that they can be changed at script level */
259246
if (uac->adv_address.s) {
260-
faked_req->set_global_address.s = pkg_malloc(uac->adv_address.len);
261-
if (!faked_req->set_global_address.s) {
247+
if (pkg_nt_str_dup(&faked_req->set_global_address, &uac->adv_address) != 0) {
262248
LM_ERR("out of pkg mem\n");
263249
goto out3;
264250
}
265-
memcpy(faked_req->set_global_address.s,
266-
uac->adv_address.s, uac->adv_address.len);
267251
} else {
268-
faked_req->set_global_address.s = NULL;
269-
faked_req->set_global_address.len = 0;
252+
faked_req->set_global_address = STR_NULL;
270253
}
254+
271255
if (uac->adv_port.s) {
272-
faked_req->set_global_port.s=pkg_malloc(uac->adv_port.len);
273-
if (!faked_req->set_global_port.s) {
256+
if (pkg_nt_str_dup(&faked_req->set_global_port, &uac->adv_port) != 0) {
274257
LM_ERR("out of pkg mem\n");
275258
goto out4;
276259
}
277-
memcpy(faked_req->set_global_port.s,
278-
uac->adv_port.s, uac->adv_port.len);
279260
} else {
280-
faked_req->set_global_port.s = NULL;
281-
faked_req->set_global_port.len = 0;
261+
faked_req->set_global_port = STR_NULL;
282262
}
283263

284264
} else {

0 commit comments

Comments
 (0)