Skip to content

Commit bd6e1fe

Browse files
authored
Extend sessions_mutex scope to avoid rogue inserts in mp viewers list (see #3246) (#3250)
1 parent b8e510c commit bd6e1fe

File tree

1 file changed

+47
-8
lines changed

1 file changed

+47
-8
lines changed

src/plugins/janus_streaming.c

+47-8
Original file line numberDiff line numberDiff line change
@@ -5733,11 +5733,11 @@ static void *janus_streaming_handler(void *data) {
57335733
janus_streaming_message_free(msg);
57345734
continue;
57355735
}
5736-
janus_mutex_unlock(&sessions_mutex);
57375736
/* Handle request */
57385737
error_code = 0;
57395738
root = NULL;
57405739
if(msg->message == NULL) {
5740+
janus_mutex_unlock(&sessions_mutex);
57415741
JANUS_LOG(LOG_ERR, "No message??\n");
57425742
error_code = JANUS_STREAMING_ERROR_NO_MESSAGE;
57435743
g_snprintf(error_cause, 512, "%s", "No message??");
@@ -5748,8 +5748,10 @@ static void *janus_streaming_handler(void *data) {
57485748
JANUS_VALIDATE_JSON_OBJECT(root, request_parameters,
57495749
error_code, error_cause, TRUE,
57505750
JANUS_STREAMING_ERROR_MISSING_ELEMENT, JANUS_STREAMING_ERROR_INVALID_ELEMENT);
5751-
if(error_code != 0)
5751+
if(error_code != 0) {
5752+
janus_mutex_unlock(&sessions_mutex);
57525753
goto error;
5754+
}
57535755
json_t *request = json_object_get(root, "request");
57545756
const char *request_text = json_string_value(request);
57555757
json_t *result = NULL;
@@ -5763,8 +5765,10 @@ static void *janus_streaming_handler(void *data) {
57635765
JANUS_VALIDATE_JSON_OBJECT(root, watch_parameters,
57645766
error_code, error_cause, TRUE,
57655767
JANUS_STREAMING_ERROR_MISSING_ELEMENT, JANUS_STREAMING_ERROR_INVALID_ELEMENT);
5766-
if(error_code != 0)
5768+
if(error_code != 0) {
5769+
janus_mutex_unlock(&sessions_mutex);
57675770
goto error;
5771+
}
57685772
if(!string_ids) {
57695773
JANUS_VALIDATE_JSON_OBJECT(root, id_parameters,
57705774
error_code, error_cause, TRUE,
@@ -5774,8 +5778,10 @@ static void *janus_streaming_handler(void *data) {
57745778
error_code, error_cause, TRUE,
57755779
JANUS_STREAMING_ERROR_MISSING_ELEMENT, JANUS_STREAMING_ERROR_INVALID_ELEMENT);
57765780
}
5777-
if(error_code != 0)
5781+
if(error_code != 0) {
5782+
janus_mutex_unlock(&sessions_mutex);
57785783
goto error;
5784+
}
57795785
json_t *id = json_object_get(root, "id");
57805786
guint64 id_value = 0;
57815787
char id_num[30], *id_value_str = NULL;
@@ -5794,6 +5800,7 @@ static void *janus_streaming_handler(void *data) {
57945800
for(i=0; i<json_array_size(mids); i++) {
57955801
json_t *s = json_array_get(mids, i);
57965802
if(!json_is_string(s)) {
5803+
janus_mutex_unlock(&sessions_mutex);
57975804
error_code = JANUS_STREAMING_ERROR_INVALID_ELEMENT;
57985805
g_snprintf(error_cause, 512, "The media array must only contain strings (mid values)");
57995806
goto error;
@@ -5814,6 +5821,7 @@ static void *janus_streaming_handler(void *data) {
58145821
string_ids ? (gpointer)id_value_str : (gpointer)&id_value);
58155822
if(mp == NULL) {
58165823
janus_mutex_unlock(&mountpoints_mutex);
5824+
janus_mutex_unlock(&sessions_mutex);
58175825
JANUS_LOG(LOG_VERB, "No such mountpoint/stream %s\n", id_value_str);
58185826
error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
58195827
g_snprintf(error_cause, 512, "No such mountpoint/stream %s", id_value_str);
@@ -5826,6 +5834,7 @@ static void *janus_streaming_handler(void *data) {
58265834
if(error_code != 0) {
58275835
janus_refcount_decrease(&mp->ref);
58285836
janus_mutex_unlock(&mountpoints_mutex);
5837+
janus_mutex_unlock(&sessions_mutex);
58295838
goto error;
58305839
}
58315840
janus_mutex_lock(&mp->mutex);
@@ -5839,6 +5848,7 @@ static void *janus_streaming_handler(void *data) {
58395848
/* Already triggered a renegotiation, and still waiting for an answer */
58405849
janus_mutex_unlock(&session->mutex);
58415850
janus_mutex_unlock(&mp->mutex);
5851+
janus_mutex_unlock(&sessions_mutex);
58425852
JANUS_LOG(LOG_ERR, "Already renegotiating mountpoint %s\n", session->mountpoint->id_str);
58435853
error_code = JANUS_STREAMING_ERROR_INVALID_STATE;
58445854
g_snprintf(error_cause, 512, "Already renegotiating mountpoint %s", session->mountpoint->id_str);
@@ -5858,6 +5868,7 @@ static void *janus_streaming_handler(void *data) {
58585868
g_snprintf(error_cause, 512, "Already watching mountpoint %s", session->mountpoint->id_str);
58595869
janus_mutex_unlock(&session->mutex);
58605870
janus_mutex_unlock(&mp->mutex);
5871+
janus_mutex_unlock(&sessions_mutex);
58615872
janus_refcount_decrease(&mp->ref);
58625873
goto error;
58635874
} else {
@@ -5870,6 +5881,7 @@ static void *janus_streaming_handler(void *data) {
58705881
janus_refcount_decrease(&mp->ref);
58715882
janus_mutex_unlock(&session->mutex);
58725883
janus_mutex_unlock(&mp->mutex);
5884+
janus_mutex_unlock(&sessions_mutex);
58735885
goto error;
58745886
}
58755887
if(!g_atomic_int_compare_and_exchange(&session->renegotiating, 0, 1)) {
@@ -5880,6 +5892,7 @@ static void *janus_streaming_handler(void *data) {
58805892
janus_refcount_decrease(&mp->ref);
58815893
janus_mutex_unlock(&session->mutex);
58825894
janus_mutex_unlock(&mp->mutex);
5895+
janus_mutex_unlock(&sessions_mutex);
58835896
goto error;
58845897
}
58855898
/* Simple renegotiation, remove the extra uneeded reference */
@@ -5894,6 +5907,7 @@ static void *janus_streaming_handler(void *data) {
58945907
if(g_list_find(mp->viewers, session) != NULL) {
58955908
janus_mutex_unlock(&session->mutex);
58965909
janus_mutex_unlock(&mp->mutex);
5910+
janus_mutex_unlock(&sessions_mutex);
58975911
janus_refcount_decrease(&mp->ref);
58985912
JANUS_LOG(LOG_ERR, "Already watching a stream (found %p in %s's viewers)...\n", session, id_value_str);
58995913
error_code = JANUS_STREAMING_ERROR_UNKNOWN_ERROR;
@@ -5926,6 +5940,7 @@ static void *janus_streaming_handler(void *data) {
59265940
session->mountpoint = NULL;
59275941
janus_mutex_unlock(&session->mutex);
59285942
janus_mutex_unlock(&mp->mutex);
5943+
janus_mutex_unlock(&sessions_mutex);
59295944
janus_refcount_decrease(&mp->ref);
59305945
JANUS_LOG(LOG_ERR, "Can't offer an SDP with no audio, video or data for this mountpoint\n");
59315946
error_code = JANUS_STREAMING_ERROR_INVALID_REQUEST;
@@ -5959,6 +5974,7 @@ static void *janus_streaming_handler(void *data) {
59595974
janus_mutex_unlock(&session->mutex);
59605975
janus_refcount_decrease(&session->ref); /* This is for the failed thread */
59615976
janus_mutex_unlock(&mp->mutex);
5977+
janus_mutex_unlock(&sessions_mutex);
59625978
janus_refcount_decrease(&mp->ref); /* This is for the failed thread */
59635979
janus_refcount_decrease(&mp->ref);
59645980
JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the on-demand thread...\n",
@@ -6018,7 +6034,8 @@ static void *janus_streaming_handler(void *data) {
60186034
session->mountpoint = NULL;
60196035
janus_mutex_unlock(&session->mutex);
60206036
janus_mutex_unlock(&mp->mutex);
6021-
janus_refcount_decrease(&mp->ref);
6037+
janus_mutex_unlock(&sessions_mutex);
6038+
janus_refcount_decrease(&mp->ref);
60226039
goto error;
60236040
}
60246041
/* In case this mountpoint is simulcasting, let's aim high by default */
@@ -6057,6 +6074,7 @@ static void *janus_streaming_handler(void *data) {
60576074
session->mountpoint = NULL;
60586075
janus_mutex_unlock(&session->mutex);
60596076
janus_mutex_unlock(&mp->mutex);
6077+
janus_mutex_unlock(&sessions_mutex);
60606078
janus_refcount_decrease(&mp->ref);
60616079
goto error;
60626080
}
@@ -6202,10 +6220,12 @@ static void *janus_streaming_handler(void *data) {
62026220
}
62036221
janus_mutex_unlock(&session->mutex);
62046222
janus_mutex_unlock(&mp->mutex);
6223+
janus_mutex_unlock(&sessions_mutex);
62056224
} else if(!strcasecmp(request_text, "watch") && jsep_sdp != NULL) {
62066225
/* New subscriber provided an offer, plugin will answer */
62076226
if(sdp_type == NULL || strcasecmp(sdp_type, "offer")) {
62086227
/* This isn't an offer, respond with an error */
6228+
janus_mutex_unlock(&sessions_mutex);
62096229
JANUS_LOG(LOG_ERR, "User provided SDP for a watch request must be an offer\n");
62106230
error_code = JANUS_STREAMING_ERROR_INVALID_SDP;
62116231
g_snprintf(error_cause, 512, "User provided SDP for a watch request must be an offer");
@@ -6214,6 +6234,7 @@ static void *janus_streaming_handler(void *data) {
62146234
char error_str[512];
62156235
janus_sdp *parsed_sdp = janus_sdp_parse(jsep_sdp, error_str, sizeof(error_str));
62166236
if(parsed_sdp == NULL) {
6237+
janus_mutex_unlock(&sessions_mutex);
62176238
JANUS_LOG(LOG_ERR, "Error parsing SDP: %s\n", error_str);
62186239
error_code = JANUS_STREAMING_ERROR_INVALID_SDP;
62196240
g_snprintf(error_cause, 512, "Error parsing SDP: %s", error_str);
@@ -6226,6 +6247,7 @@ static void *janus_streaming_handler(void *data) {
62266247
error_code, error_cause, TRUE,
62276248
JANUS_STREAMING_ERROR_MISSING_ELEMENT, JANUS_STREAMING_ERROR_INVALID_ELEMENT);
62286249
if(error_code != 0) {
6250+
janus_mutex_unlock(&sessions_mutex);
62296251
janus_sdp_destroy(parsed_sdp);
62306252
goto error;
62316253
}
@@ -6239,6 +6261,7 @@ static void *janus_streaming_handler(void *data) {
62396261
JANUS_STREAMING_ERROR_MISSING_ELEMENT, JANUS_STREAMING_ERROR_INVALID_ELEMENT);
62406262
}
62416263
if(error_code != 0) {
6264+
janus_mutex_unlock(&sessions_mutex);
62426265
janus_sdp_destroy(parsed_sdp);
62436266
goto error;
62446267
}
@@ -6258,6 +6281,7 @@ static void *janus_streaming_handler(void *data) {
62586281
string_ids ? (gpointer)id_value_str : (gpointer)&id_value);
62596282
if(mp == NULL) {
62606283
janus_mutex_unlock(&mountpoints_mutex);
6284+
janus_mutex_unlock(&sessions_mutex);
62616285
janus_sdp_destroy(parsed_sdp);
62626286
JANUS_LOG(LOG_VERB, "No such mountpoint/stream %s\n", id_value_str);
62636287
error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
@@ -6271,6 +6295,7 @@ static void *janus_streaming_handler(void *data) {
62716295
if(error_code != 0) {
62726296
janus_refcount_decrease(&mp->ref);
62736297
janus_mutex_unlock(&mountpoints_mutex);
6298+
janus_mutex_unlock(&sessions_mutex);
62746299
janus_sdp_destroy(parsed_sdp);
62756300
goto error;
62766301
}
@@ -6284,13 +6309,15 @@ static void *janus_streaming_handler(void *data) {
62846309
g_snprintf(error_cause, 512, "Already watching mountpoint %s", session->mountpoint->id_str);
62856310
janus_mutex_unlock(&session->mutex);
62866311
janus_mutex_unlock(&mp->mutex);
6312+
janus_mutex_unlock(&sessions_mutex);
62876313
janus_refcount_decrease(&mp->ref);
62886314
janus_sdp_destroy(parsed_sdp);
62896315
goto error;
62906316
}
62916317
if(g_list_find(mp->viewers, session) != NULL) {
62926318
janus_mutex_unlock(&session->mutex);
62936319
janus_mutex_unlock(&mp->mutex);
6320+
janus_mutex_unlock(&sessions_mutex);
62946321
janus_refcount_decrease(&mp->ref);
62956322
JANUS_LOG(LOG_ERR, "Already watching a stream (found %p in %s's viewers)...\n", session, id_value_str);
62966323
error_code = JANUS_STREAMING_ERROR_UNKNOWN_ERROR;
@@ -6495,7 +6522,9 @@ static void *janus_streaming_handler(void *data) {
64956522
janus_refcount_increase(&session->ref);
64966523
janus_mutex_unlock(&session->mutex);
64976524
janus_mutex_unlock(&mp->mutex);
6525+
janus_mutex_unlock(&sessions_mutex);
64986526
} else if(!strcasecmp(request_text, "start")) {
6527+
janus_mutex_unlock(&sessions_mutex);
64996528
if(session->mountpoint == NULL) {
65006529
JANUS_LOG(LOG_VERB, "Can't start: no mountpoint set\n");
65016530
error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
@@ -6529,6 +6558,7 @@ static void *janus_streaming_handler(void *data) {
65296558
gateway->notify_event(&janus_streaming_plugin, session->handle, info);
65306559
}
65316560
} else if(!strcasecmp(request_text, "pause")) {
6561+
janus_mutex_unlock(&sessions_mutex);
65326562
if(session->mountpoint == NULL) {
65336563
JANUS_LOG(LOG_VERB, "Can't pause: no mountpoint set\n");
65346564
error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
@@ -6549,6 +6579,7 @@ static void *janus_streaming_handler(void *data) {
65496579
gateway->notify_event(&janus_streaming_plugin, session->handle, info);
65506580
}
65516581
} else if(!strcasecmp(request_text, "configure")) {
6582+
janus_mutex_unlock(&sessions_mutex);
65526583
janus_streaming_mountpoint *mp = session->mountpoint;
65536584
if(mp == NULL) {
65546585
JANUS_LOG(LOG_VERB, "Can't configure: not on a mountpoint\n");
@@ -6563,7 +6594,7 @@ static void *janus_streaming_handler(void *data) {
65636594
json_t *audio = json_object_get(root, "audio");
65646595
json_t *video = json_object_get(root, "video");
65656596
json_t *data = json_object_get(root, "data");
6566-
6597+
65676598
/* We use an array of streams to state the changes we want to make,
65686599
* were for each stream we specify the 'mid' to impact (e.g., send) */
65696600
json_t *streams = json_object_get(root, "streams");
@@ -6604,7 +6635,7 @@ static void *janus_streaming_handler(void *data) {
66046635
json_array_append_new(streams, stream);
66056636
json_object_set_new(root, "streams", streams);
66066637
}
6607-
6638+
66086639
size_t i = 0;
66096640
size_t streams_size = json_array_size(streams);
66106641
for(i=0; i<streams_size; i++) {
@@ -6651,7 +6682,7 @@ static void *janus_streaming_handler(void *data) {
66516682
if(error_code != 0) {
66526683
goto error;
66536684
}
6654-
6685+
66556686
if(mp->streaming_source == janus_streaming_source_rtp) {
66566687
/* Enforce the requested changes */
66576688
for(i=0; i<json_array_size(streams); i++) {
@@ -6811,6 +6842,7 @@ static void *janus_streaming_handler(void *data) {
68116842
janus_streaming_mountpoint *oldmp = session->mountpoint;
68126843
if(oldmp == NULL) {
68136844
janus_mutex_unlock(&session->mutex);
6845+
janus_mutex_unlock(&sessions_mutex);
68146846
JANUS_LOG(LOG_VERB, "Can't switch: not on a mountpoint\n");
68156847
error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
68166848
g_snprintf(error_cause, 512, "Can't switch: not on a mountpoint");
@@ -6819,6 +6851,7 @@ static void *janus_streaming_handler(void *data) {
68196851
if(oldmp->streaming_type != janus_streaming_type_live ||
68206852
oldmp->streaming_source != janus_streaming_source_rtp) {
68216853
janus_mutex_unlock(&session->mutex);
6854+
janus_mutex_unlock(&sessions_mutex);
68226855
JANUS_LOG(LOG_VERB, "Can't switch: not on a live RTP mountpoint\n");
68236856
error_code = JANUS_STREAMING_ERROR_CANT_SWITCH;
68246857
g_snprintf(error_cause, 512, "Can't switch: not on a live RTP mountpoint");
@@ -6836,6 +6869,7 @@ static void *janus_streaming_handler(void *data) {
68366869
}
68376870
if(error_code != 0) {
68386871
janus_mutex_unlock(&session->mutex);
6872+
janus_mutex_unlock(&sessions_mutex);
68396873
janus_refcount_decrease(&oldmp->ref);
68406874
goto error;
68416875
}
@@ -6855,6 +6889,7 @@ static void *janus_streaming_handler(void *data) {
68556889
if(mp == NULL || g_atomic_int_get(&mp->destroyed)) {
68566890
janus_mutex_unlock(&mountpoints_mutex);
68576891
janus_mutex_unlock(&session->mutex);
6892+
janus_mutex_unlock(&sessions_mutex);
68586893
JANUS_LOG(LOG_VERB, "No such mountpoint/stream %s\n", id_value_str);
68596894
error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
68606895
g_snprintf(error_cause, 512, "No such mountpoint/stream %s", id_value_str);
@@ -6867,6 +6902,7 @@ static void *janus_streaming_handler(void *data) {
68676902
janus_refcount_decrease(&mp->ref);
68686903
janus_mutex_unlock(&mountpoints_mutex);
68696904
janus_mutex_unlock(&session->mutex);
6905+
janus_mutex_unlock(&sessions_mutex);
68706906
JANUS_LOG(LOG_VERB, "Can't switch: target is not a live RTP mountpoint\n");
68716907
error_code = JANUS_STREAMING_ERROR_CANT_SWITCH;
68726908
g_snprintf(error_cause, 512, "Can't switch: target is not a live RTP mountpoint");
@@ -6937,6 +6973,7 @@ static void *janus_streaming_handler(void *data) {
69376973
g_atomic_int_set(&session->paused, 0);
69386974
janus_mutex_unlock(&session->mutex);
69396975
janus_mutex_unlock(&mp->mutex);
6976+
janus_mutex_unlock(&sessions_mutex);
69406977
/* Done with the request, remove the references we took for that */
69416978
janus_refcount_decrease(&oldmp->ref);
69426979
janus_refcount_decrease(&mp->ref);
@@ -6951,6 +6988,7 @@ static void *janus_streaming_handler(void *data) {
69516988
gateway->notify_event(&janus_streaming_plugin, session->handle, info);
69526989
}
69536990
} else if(!strcasecmp(request_text, "stop")) {
6991+
janus_mutex_unlock(&sessions_mutex);
69546992
if(g_atomic_int_get(&session->stopping) || !g_atomic_int_get(&session->started)) {
69556993
/* Been there, done that: ignore */
69566994
janus_streaming_message_free(msg);
@@ -6971,6 +7009,7 @@ static void *janus_streaming_handler(void *data) {
69717009
/* Tell the core to tear down the PeerConnection, hangup_media will do the rest */
69727010
gateway->close_pc(session->handle);
69737011
} else {
7012+
janus_mutex_unlock(&sessions_mutex);
69747013
JANUS_LOG(LOG_VERB, "Unknown request '%s'\n", request_text);
69757014
error_code = JANUS_STREAMING_ERROR_INVALID_REQUEST;
69767015
g_snprintf(error_cause, 512, "Unknown request '%s'", request_text);

0 commit comments

Comments
 (0)