[vlc-commits] [Git][videolan/vlc][3.0.x] 12 commits: demux: ps: always clean the track format
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Fri Apr 17 11:37:49 UTC 2026
Felix Paul Kühne pushed to branch 3.0.x at VideoLAN / VLC
Commits:
88b9e431 by Alaric Senat at 2026-04-17T12:15:14+02:00
demux: ps: always clean the track format
Conditionally cleaning the track format leads to leaks on ill-formed ps
packets. Usually when a track started allocating fmt metadata and the
input has an unexpected EOF.
The format is always zero initialized so we can count on es_format_Clean
not to double free.
Fixes https://issues.oss-fuzz.com/issues/42503008
Fixes #29013
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/vlc
(cherry picked from commit d9f6f6a500e4394c194ab4dde7f5d5ba3c1e9d74)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
a0d586e7 by Steve Lhomme at 2026-04-17T12:15:14+02:00
gstreamer: remove unneeded includes
We don't use anything specific to these headers that is not include by gstvlcpictureplaneallocator.h.
Fixes #29604
(cherry picked from commit eea0bacf625d910e37630743c864f96704047936)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
fb00f9b5 by Steve Lhomme at 2026-04-17T12:15:14+02:00
test: adaptive: fix designated initializer usage in C++
Co-authored-by: Alexandre Janniaux <ajanni at videolabs.io>
(cherry picked from commit 4ca9a6ae6c4be8a251c99b23a3a182a0a2cfcb7c) (edited)
edited:
- VLC 3 doesn't have the same parameters in dropesout (no DummyEsOut or callback structure)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
bf427b5c by unichronic at 2026-04-17T12:15:14+02:00
mkv: fix OOM vulnerability when parsing oversized child elements
Properly restricts the boundaries of child elements (i_ulev == 0) to their parent's boundaries, preventing libebml from bypassing MaxDataSize and allocating enormous amounts of memory when encountering spoofed UpperLevel IDs.
(cherry picked from commit 4bc8283e46de625057499127441e082c295ed2e4)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
044a49f7 by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: ts: fix comparison of MPEG syncword
We don't want to compare with 0x00, 0x00, 0x01, 0x00.
Introduced in bfb2e970783cfcf9635556ca174bcd5691cbbbc2.
(cherry picked from commit 01f488820527ffb05dcae19f8ea66cd10c70c32b)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
117fdf3e by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: mkv: debug the Dummy element buggy position
(cherry picked from commit f87900ad96250fd739538ffa9328f1f72206e592)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
7285bc33 by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: mkv: use size_t for levels in m_el table
It should never be negative.
(cherry picked from commit 344e4f192a6342e8ae0c46c3fcdeeff047964ceb) (rebased)
rebased:
- VLC 3 uses EbmlStream instead of matroska_iostream_c
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
efc4854b by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: mkv: remove else after return
(cherry picked from commit 1e4088406663104e6ea810b1b30ec32f3db8e550)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
7d55776f by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: mkv: only read the edition name once
(cherry picked from commit 0657a7baf5533c51c2c81c29352ca398cce344e7)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
cdcd4b08 by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: mkv: fix title number reading
We are reading the 3rd and 4th bytes in the buffer.
(cherry picked from commit 65f4d092a6a54e376f063587bdd15e47fa9614e6) (edited)
edited:
- in VLC 3 the file is still called chapter_command.cpp
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
2b948be6 by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: ts: check block skip size
The result of PKTHeaderAndAFSize() is not checked against the available data.
There's a cap at 187 bytes but the block may contain less data (EOF).
We can't properly subtract i_skip from p_pkt->i_buffer.
If there is too much data to skip the pcr won't be updated.
(cherry picked from commit 93e847d1c02e8bb55c46f1d9c511e95e9e9bc2ec) (rebased)
rebased:
- VLC 4 uses a PKTHeaderAndAFSize() function to get the skip value
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
ee9d85e1 by Steve Lhomme at 2026-04-17T12:15:14+02:00
demux: ts: check block has enough data before checking payload flags
(cherry picked from commit 417a06caa26df76a51d09bdd5361ef4d9b7c96e3) (rebased)
rebased:
- VLC 4 uses a PKTHeaderAndAFSize() function to get the skip value
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
- - - - -
9 changed files:
- modules/codec/gstreamer/gstvlcvideopool.h
- modules/demux/adaptive/test/plumbing/FakeEsOut.cpp
- modules/demux/mkv/Ebml_parser.cpp
- modules/demux/mkv/Ebml_parser.hpp
- modules/demux/mkv/chapter_command.cpp
- modules/demux/mkv/demux.cpp
- modules/demux/mpeg/ps.c
- modules/demux/mpeg/ts.c
- modules/demux/mpeg/ts_hotfixes.c
Changes:
=====================================
modules/codec/gstreamer/gstvlcvideopool.h
=====================================
@@ -27,9 +27,6 @@
#ifndef VLC_GST_VIDEO_POOL_H
#define VLC_GST_VIDEO_POOL_H
-#include <gst/gstbufferpool.h>
-#include <gst/video/gstvideopool.h>
-
#include "gstvlcpictureplaneallocator.h"
typedef struct _GstVlcVideoPool GstVlcVideoPool;
=====================================
modules/demux/adaptive/test/plumbing/FakeEsOut.cpp
=====================================
@@ -365,16 +365,16 @@ static int check0(es_out_t *out, struct context *, FakeESOut *fakees)
int FakeEsOut_test()
{
struct context ctx = {VLC_TICK_INVALID,VLC_TICK_INVALID,VLC_TICK_INVALID};
- struct dropesout dummy = {
- .ctx = &ctx,
- .esout = {
+ struct dropesout dummy = {};
+ dummy.ctx = &ctx;
+ dummy.esout = {
.pf_add = dummy_callback_add,
.pf_send = dummy_callback_send,
.pf_del = dummy_callback_del,
.pf_control = dummy_callback_control,
.pf_destroy = dummy_callback_destroy,
.p_sys = nullptr,
- } };
+ };
int(* const tests[3])(es_out_t *, struct context *, FakeESOut *)
= { check0, check1, check2 };
=====================================
modules/demux/mkv/Ebml_parser.cpp
=====================================
@@ -51,7 +51,7 @@ EbmlParser::~EbmlParser( void )
return;
}
- for( int i = 1; i <= mi_level; i++ )
+ for( size_t i = 1; i <= mi_level; i++ )
{
if( !mb_keep )
{
@@ -75,6 +75,7 @@ void EbmlParser::Up( void )
msg_Warn( p_demux, "MKV/Ebml Parser: Up cannot escape itself" );
}
+ assert(mi_user_level != 0);
mi_user_level--;
}
@@ -146,6 +147,15 @@ EbmlElement *EbmlParser::Get( bool allow_overshoot )
EbmlElement *ret = m_got;
m_got = NULL;
+ if( mi_level > 0 && m_el[mi_level-1]->IsFiniteSize() && ret->IsFiniteSize() &&
+ ret->GetEndPosition() > m_el[mi_level-1]->GetEndPosition() )
+ {
+ msg_Err( p_demux, "EBML element at %" PRIu64 " extends beyond parent boundary (%" PRIu64 " beyond %" PRIu64 ")",
+ m_el[mi_level]->GetElementPosition(), m_el[mi_level]->GetEndPosition(), m_el[mi_level-1]->GetEndPosition() );
+ delete ret;
+ m_el[mi_level] = NULL;
+ return NULL;
+ }
return ret;
}
@@ -247,7 +257,7 @@ next:
}
return NULL;
}
- else if( m_el[mi_level] == NULL )
+ if( m_el[mi_level] == NULL )
{
msg_Dbg( p_demux,"MKV/Ebml Parser: m_el[mi_level] == NULL" );
/* go back to the end of the parent */
@@ -269,7 +279,8 @@ next:
p_prev && p_prev->IsFiniteSize() &&
p_prev->GetEndPosition() != m_el[mi_level]->GetElementPosition() )
{
- msg_Err( p_demux, "Dummy Element at unexpected position... corrupted file?" );
+ msg_Err( p_demux, "Dummy Element at unexpected position (%" PRIu64 " instead of %" PRIu64 ")... corrupted file?",
+ m_el[mi_level]->GetElementPosition(), p_prev->GetEndPosition() );
b_bad_position = true;
}
@@ -338,7 +349,7 @@ next:
bool EbmlParser::IsTopPresent( EbmlElement *el ) const
{
- for( int i = 0; i < mi_level; i++ )
+ for( size_t i = 0; i < mi_level; i++ )
{
if( m_el[i] && m_el[i] == el )
return true;
=====================================
modules/demux/mkv/Ebml_parser.hpp
=====================================
@@ -55,12 +55,12 @@ class EbmlParser
demux_t *p_demux;
EbmlStream *m_es;
- int mi_level;
+ size_t mi_level;
EbmlElement *m_el[M_EL_MAXSIZE];
EbmlElement *m_got;
- int mi_user_level;
+ size_t mi_user_level;
bool mb_keep;
/* Allow dummy/unknown EBML elements */
bool mb_dummy;
=====================================
modules/demux/mkv/chapter_command.cpp
=====================================
@@ -55,7 +55,7 @@ void chapter_codec_cmds_c::AddCommand( const KaxChapterProcessCommand & command
int16 dvd_chapter_codec_c::GetTitleNumber()
{
- if ( p_private_data != nullptr && p_private_data->GetSize() >= 3)
+ if ( p_private_data != nullptr && p_private_data->GetSize() > 3)
{
const binary* p_data = p_private_data->GetBuffer();
if ( p_data[0] == MATROSKA_DVD_LEVEL_SS )
=====================================
modules/demux/mkv/demux.cpp
=====================================
@@ -668,8 +668,9 @@ bool demux_sys_t::PreloadLinked()
// TODO use a name for each edition, let the TITLE deal with a codec name
if ( p_title->psz_name == NULL )
{
- if( p_ved->GetMainName().length() )
- p_title->psz_name = strdup( p_ved->GetMainName().c_str() );
+ const auto edition_name = p_ved->GetMainName();
+ if( edition_name.length() )
+ p_title->psz_name = strdup( edition_name.c_str() );
else
{
/* Check in tags if the edition has a name */
=====================================
modules/demux/mpeg/ps.c
=====================================
@@ -270,11 +270,9 @@ static void Close( vlc_object_t *p_this )
for( i = 0; i < PS_TK_COUNT; i++ )
{
ps_track_t *tk = &p_sys->tk[i];
- if( tk->b_configured )
- {
- es_format_Clean( &tk->fmt );
- if( tk->es ) es_out_Del( p_demux->out, tk->es );
- }
+ es_format_Clean( &tk->fmt );
+ if( tk->b_configured && tk->es != NULL )
+ es_out_Del( p_demux->out, tk->es );
}
ps_psm_destroy( &p_sys->psm );
=====================================
modules/demux/mpeg/ts.c
=====================================
@@ -1961,7 +1961,7 @@ static int SeekToTime( demux_t *p_demux, const ts_pmt_t *p_pmt, vlc_tick_t i_see
}
}
- if( i_pktpcr == TS_90KHZ_INVALID && p_pid->type == TYPE_STREAM &&
+ if( p_pkt->i_buffer > 4 && p_pkt->i_buffer > i_skip && i_pktpcr == TS_90KHZ_INVALID && p_pid->type == TYPE_STREAM &&
ts_stream_Find_es( p_pid->u.p_stream, p_pmt ) &&
(p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
(p_pkt->p_buffer[3] & 0xD0) == 0x10 /* Has payload but is not encrypted */
@@ -2057,6 +2057,8 @@ static int ProbeChunk( demux_t *p_demux, int i_program, bool b_end, ts_90khz_t *
if ( b_adaptfield ) // adaptation field
i_skip += 1 + __MIN(p_pkt->p_buffer[4], 182);
+ if (p_pkt->i_buffer > i_skip)
+ {
if ( VLC_SUCCESS == ParsePESHeader( VLC_OBJECT(p_demux), &p_pkt->p_buffer[i_skip],
p_pkt->i_buffer - i_skip, &i_skip,
&i_dts, &i_pts, &i_stream_id, NULL ) )
@@ -2066,6 +2068,7 @@ static int ProbeChunk( demux_t *p_demux, int i_program, bool b_end, ts_90khz_t *
else if( i_pts != TS_90KHZ_INVALID )
*pi_pcr = i_pts;
}
+ }
}
if( *pi_pcr != TS_90KHZ_INVALID )
=====================================
modules/demux/mpeg/ts_hotfixes.c
=====================================
@@ -185,7 +185,7 @@ void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_
{
pid->probed.i_fourcc = VLC_CODEC_H264;
}
- else if( !memcmp( p_data, "\x00\x00\x01", 4 ) )
+ else if( !memcmp( p_data, "\x00\x00\x01", 3 ) )
{
pid->probed.i_fourcc = VLC_CODEC_MPGV;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/871b608f56a732b1156a21bd5d923f8c0c4a6004...ee9d85e1d2de0da4456d2c03b39d706eed0527b0
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/871b608f56a732b1156a21bd5d923f8c0c4a6004...ee9d85e1d2de0da4456d2c03b39d706eed0527b0
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list