Skip to content

Commit 43b696d

Browse files
NormBliviuchircu
authored andcommitted
janus: fix pkg memory leaks in cJSON_Print/cJSON_Parse paths
The janus module uses cJSON_InitHooks() to route all cJSON allocations through OpenSIPS pkg_malloc. Three call sites had missing cleanup: - janus_ipc_send_request(): cJSON_Print() result was copied to shm via shm_nt_str_dup() but the pkg-allocated original was never freed. Also added a NULL check -- under pkg exhaustion cJSON_Print returns NULL and the subsequent strlen(NULL) causes a crash. - w_janus_send_request(): the cJSON tree from cJSON_Parse() was passed to janus_ipc_send_request() (which serializes it to shm) but cJSON_Delete() was never called afterward. Also added cleanup on the get_janus_connection_by_id() failure path. - janus_raise_event() and handle_janus_json_request(): added NULL checks after cJSON_Print(). Fixed missing pkg_free(full_json) on the shm_strdup() failure path in handle_janus_json_request(). Together these leak ~350 bytes of pkg memory per janus_send_request() call, leading to SIP worker pkg exhaustion and crash under sustained load. Fixes #3712
1 parent b25788d commit 43b696d

3 files changed

Lines changed: 20 additions & 0 deletions

File tree

modules/janus/janus_common.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ int janus_raise_event(janus_connection *conn, cJSON *request)
112112
}
113113

114114
full_json = cJSON_Print(request);
115+
if (!full_json) {
116+
LM_ERR("cJSON_Print failed\n");
117+
goto err_free_params;
118+
}
115119
cJSON_Minify(full_json);
116120
full_json_s.s = full_json;
117121
full_json_s.len = strlen(full_json);
@@ -191,10 +195,15 @@ int handle_janus_json_request(janus_connection *conn, cJSON *request)
191195
}
192196

193197
full_json = cJSON_Print(request);
198+
if (!full_json) {
199+
LM_ERR("cJSON_Print failed\n");
200+
return 1;
201+
}
194202
cJSON_Minify(full_json);
195203

196204
reply->text.s = shm_strdup(full_json);
197205
if (reply->text.s == NULL) {
206+
pkg_free(full_json);
198207
/* we're out of mem, let the requestor timeout, don't disconnect janus */
199208
return 1;
200209
}

modules/janus/janus_mod.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,14 @@ static int w_janus_send_request(struct sip_msg *msg, str *janus_id,str *request,
208208

209209
if ((conn = get_janus_connection_by_id(janus_id)) == NULL) {
210210
LM_ERR("Unknown JANUS ID %.*s\n",janus_id->len,janus_id->s);
211+
cJSON_Delete(j_request);
211212
return -1;
212213
}
213214

214215
LM_DBG("Found our conn, prep to send out %.*s !! \n",request->len,request->s);
215216

216217
reply_id = janus_ipc_send_request(conn,j_request);
218+
cJSON_Delete(j_request); /* tree was serialized to shm; free pkg copy */
217219
if (reply_id == 0) {
218220
LM_ERR("Failed to queue request %.*s towards %.*s\n",
219221
request->len,request->s,

modules/janus/janus_proc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,14 +282,23 @@ uint64_t janus_ipc_send_request(janus_connection *sock, cJSON *janus_cmd)
282282
lock_stop_write(sock->lists_lk);
283283

284284
full_cmd.s = cJSON_Print(janus_cmd);
285+
if (!full_cmd.s) {
286+
shm_free(cmd);
287+
LM_ERR("cJSON_Print failed (pkg OOM)\n");
288+
return 0;
289+
}
285290
full_cmd.len = strlen(full_cmd.s);
286291

287292
if (shm_nt_str_dup(&cmd->janus_cmd, &full_cmd) != 0) {
293+
pkg_free(full_cmd.s);
288294
shm_free(cmd);
289295
LM_ERR("oom\n");
290296
return 0;
291297
}
292298

299+
/* cJSON_Print() allocates from pkg via module hooks; free after shm copy */
300+
pkg_free(full_cmd.s);
301+
293302
janus_transaction_id = cmd->janus_transaction_id;
294303

295304
if (ipc_send_job(*janus_mgr_process_no, ipc_hdl_run_janus, cmd) != 0) {

0 commit comments

Comments
 (0)