[vlc-commits] es_out: add priv controls to set/unset vlc_es_id_t
Thomas Guillem
git at videolan.org
Fri Feb 28 20:45:59 CET 2020
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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:
More information about the vlc-commits
mailing list