vlc | branch: master | Thomas Guillem <[email protected]> | Thu Feb 27 15:33:28 2020 +0100| [4a6a439a74dfb658a708e342e84992e06f3f91b4] | committer: Thomas Guillem
es_out: add priv controls to set/unset vlc_es_id_t It's now illegal to control a es_out_id_t directly from input.c. A refcounted vlc_es_id_t should be used instead. It fixes a potential (but not enabled) use-after-free if a es_out_id_t was passed to the timeshift thread. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4a6a439a74dfb658a708e342e84992e06f3f91b4 --- src/input/es_out.c | 16 ++++++++++++++++ src/input/es_out.h | 17 +++++++++++++++++ src/input/es_out_timeshift.c | 3 +++ src/input/input.c | 10 +++------- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/input/es_out.c b/src/input/es_out.c index bb24305b15..81083e56c5 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -3278,6 +3278,22 @@ static int EsOutVaPrivControlLocked( es_out_t *out, int query, va_list args ) EsOutTerminate( out ); return VLC_SUCCESS; } + case ES_OUT_PRIV_SET_ES: + case ES_OUT_PRIV_UNSET_ES: + case ES_OUT_PRIV_RESTART_ES: + { + vlc_es_id_t *es_id = va_arg( args, vlc_es_id_t * ); + es_out_id_t *es = vlc_es_id_get_out( es_id ); + int new_query; + switch( query ) + { + case ES_OUT_PRIV_SET_ES: new_query = ES_OUT_SET_ES; break; + case ES_OUT_PRIV_UNSET_ES: new_query = ES_OUT_UNSET_ES; break; + case ES_OUT_PRIV_RESTART_ES: new_query = ES_OUT_RESTART_ES; break; + default: vlc_assert_unreachable(); + } + return EsOutControlLocked( out, new_query, es ); + } case ES_OUT_PRIV_GET_WAKE_UP: { vlc_tick_t *pi_wakeup = va_arg( args, vlc_tick_t* ); diff --git a/src/input/es_out.h b/src/input/es_out.h index 67b2a1e96a..6d9d60619d 100644 --- a/src/input/es_out.h +++ b/src/input/es_out.h @@ -40,6 +40,11 @@ enum es_out_query_private_e /* set/get mode */ ES_OUT_PRIV_SET_MODE, /* arg1= int */ + /* Same than ES_OUT_SET_ES/ES_OUT_UNSET_ES/ES_OUT_RESTART_ES, but with vlc_es_id_t * */ + ES_OUT_PRIV_SET_ES, /* arg1= vlc_es_id_t* */ + ES_OUT_PRIV_UNSET_ES, /* arg1= vlc_es_id_t* res=can fail */ + ES_OUT_PRIV_RESTART_ES, /* arg1= vlc_es_id_t* */ + /* Get date to wait before demuxing more data */ ES_OUT_PRIV_GET_WAKE_UP, /* arg1=vlc_tick_t* res=cannot fail */ @@ -121,6 +126,18 @@ static inline void es_out_SetMode( es_out_t *p_out, int i_mode ) int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_MODE, i_mode ); assert( !i_ret ); } +static inline int es_out_SetEs( es_out_t *p_out, vlc_es_id_t *id ) +{ + return es_out_PrivControl( p_out, ES_OUT_PRIV_SET_ES, id ); +} +static inline int es_out_UnsetEs( es_out_t *p_out, vlc_es_id_t *id ) +{ + return es_out_PrivControl( p_out, ES_OUT_PRIV_UNSET_ES, id ); +} +static inline int es_out_RestartEs( es_out_t *p_out, vlc_es_id_t *id ) +{ + return es_out_PrivControl( p_out, ES_OUT_PRIV_RESTART_ES, id ); +} static inline vlc_tick_t es_out_GetWakeup( es_out_t *p_out ) { vlc_tick_t i_wu; diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c index ff8de86b82..96229a9a0e 100644 --- a/src/input/es_out_timeshift.c +++ b/src/input/es_out_timeshift.c @@ -789,6 +789,9 @@ static int PrivControlLocked( es_out_t *p_out, int i_query, va_list args ) case ES_OUT_PRIV_GET_GROUP_FORCED: return es_out_vaPrivControl( p_sys->p_out, i_query, args ); /* Invalid queries for this es_out level */ + case ES_OUT_PRIV_SET_ES: + case ES_OUT_PRIV_UNSET_ES: + case ES_OUT_PRIV_RESTART_ES: case ES_OUT_PRIV_SET_ES_LIST: case ES_OUT_PRIV_SET_ES_BY_ID: case ES_OUT_PRIV_RESTART_ES_BY_ID: diff --git a/src/input/input.c b/src/input/input.c index 94458a68ce..0834bbd838 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -2006,9 +2006,7 @@ static bool Control( input_thread_t *p_input, break; case INPUT_CONTROL_SET_ES: - if( es_out_Control( input_priv(p_input)->p_es_out_display, - ES_OUT_SET_ES, vlc_es_id_get_out( param.id ) ) - == VLC_SUCCESS ) + if( es_out_SetEs( priv->p_es_out_display, param.id ) == VLC_SUCCESS ) demux_Control( input_priv(p_input)->master->p_demux, DEMUX_SET_ES, vlc_es_id_GetInputId( param.id ) ); break; @@ -2041,12 +2039,10 @@ static bool Control( input_thread_t *p_input, break; } case INPUT_CONTROL_UNSET_ES: - es_out_Control( input_priv(p_input)->p_es_out_display, - ES_OUT_UNSET_ES, vlc_es_id_get_out(param.id) ); + es_out_UnsetEs( priv->p_es_out_display, param.id ); break; case INPUT_CONTROL_RESTART_ES: - es_out_Control( input_priv(p_input)->p_es_out_display, - ES_OUT_RESTART_ES, vlc_es_id_get_out( param.id ) ); + es_out_RestartEs( priv->p_es_out_display, param.id ); break; case INPUT_CONTROL_SET_VIEWPOINT: _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
