From 44021b1c61ce9462b925e1733cd65c7a32d23a4c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 10 Jul 2017 19:13:27 -0500 Subject: [PATCH] FS-10472: [mod_conference] Invalid free in personal canvas mode --- .../mod_conference/conference_member.c | 7 ++++--- .../mod_conference/conference_video.c | 7 +++++-- src/switch_core_video.c | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index e9248c2548..ea80527ac8 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -1161,9 +1161,6 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m } member->avatar_patched = 0; - switch_img_free(&member->avatar_png_img); - switch_img_free(&member->video_mute_img); - switch_img_free(&member->pcanvas_img); switch_mutex_lock(conference->mutex); switch_mutex_lock(conference->member_mutex); switch_mutex_lock(member->audio_in_mutex); @@ -1194,6 +1191,10 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m last = imember; } + switch_img_free(&member->avatar_png_img); + switch_img_free(&member->video_mute_img); + switch_img_free(&member->pcanvas_img); + switch_thread_rwlock_unlock(member->rwlock); /* Close Unused Handles */ diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 1994ec08f9..f32461cc50 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -420,8 +420,10 @@ void conference_video_reset_layer(mcu_layer_t *layer) } switch_img_free(&layer->img); - layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, layer->screen_w, layer->screen_h, 1); - switch_assert(layer->img); + if (layer->screen_w && layer->screen_h) { + layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, layer->screen_w, layer->screen_h, 1); + switch_assert(layer->img); + } conference_video_clear_layer(layer); switch_img_free(&layer->cur_img); @@ -2570,6 +2572,7 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t if (switch_channel_test_flag(member->channel, CF_VIDEO_READY)) { do { + pop = NULL; if (switch_queue_trypop(member->video_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { switch_img_free(&img); img = (switch_image_t *)pop; diff --git a/src/switch_core_video.c b/src/switch_core_video.c index 0a5dcffc6f..7c010b7c0b 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -190,6 +190,7 @@ SWITCH_DECLARE(switch_image_t *)switch_img_alloc(switch_image_t *img, unsigned int align) { #ifdef SWITCH_HAVE_VPX + switch_image_t *r = NULL; #ifdef HAVE_LIBGD if (fmt == SWITCH_IMG_FMT_GD) { gdImagePtr gd = gdImageCreateTrueColor(d_w, d_h); @@ -212,7 +213,14 @@ SWITCH_DECLARE(switch_image_t *)switch_img_alloc(switch_image_t *img, } #endif - return (switch_image_t *)vpx_img_alloc((vpx_image_t *)img, (vpx_img_fmt_t)fmt, d_w, d_h, align); + switch_assert(d_w > 0); + switch_assert(d_h > 0); + r = (switch_image_t *)vpx_img_alloc((vpx_image_t *)img, (vpx_img_fmt_t)fmt, d_w, d_h, align); + switch_assert(r); + switch_assert(r->d_w == d_w); + switch_assert(r->d_h = d_h); + + return r; #else return NULL; #endif @@ -291,6 +299,9 @@ SWITCH_DECLARE(void) switch_img_free(switch_image_t **img) switch_safe_free((*img)->user_priv); } } + switch_assert((*img)->fmt <= SWITCH_IMG_FMT_I44016); + switch_assert((*img)->d_w <= 7860 && (*img)->d_w > 0); + switch_assert((*img)->d_h <= 4320 && (*img)->d_h > 0); vpx_img_free((vpx_image_t *)*img); *img = NULL; } @@ -3139,6 +3150,9 @@ SWITCH_DECLARE(switch_status_t) switch_img_scale(switch_image_t *src, switch_ima dest = *destP; } + switch_assert(width > 0); + switch_assert(height > 0); + if (dest && src->fmt != dest->fmt) switch_img_free(&dest); if (!dest) dest = switch_img_alloc(NULL, src->fmt, width, height, 1);