Fix heap overflow in time formatting and disable ante/post exec by de…#1260
Fix heap overflow in time formatting and disable ante/post exec by de…#1260armin5872 wants to merge 1 commit into
Conversation
|
|
||
| static int ante_post_commands_allowed() | ||
| { | ||
| const char *e = getenv("MLT_CONSUMER_ANTE_POST_ALLOWED"); |
There was a problem hiding this comment.
This should be documented in mlt_consumer.h using \envvar. See the other headers in the same directory for example. Likewise, these "anti" and "post" properties were intentionally undocumented because they are legacy cruft I did not really want people to use. Briefly document them as well using \properties \em with a suffix of " (DEPRECATED)".
| mlt_log(MLT_CONSUMER_SERVICE(self), | ||
| MLT_LOG_WARNING, |
There was a problem hiding this comment.
Prefer the logging macros mlt_log_... instead of this form. Not a required change, but if you can get around to it.
| * it cannot be exceeded even for pathological/attacker-supplied frame counts | ||
| * or frame rates (see time_smpte_from_frames() and time_clock_from_frames()). | ||
| */ | ||
| #define MLT_TIME_STRING_MAX 64 |
There was a problem hiding this comment.
64 is too big. Simply look at the sprintf format args. Leave it at the original 32.
| double hours_d = frames / (fps * 3600); | ||
| if (hours_d > 999999.0) | ||
| hours_d = 999999.0; | ||
| else if (hours_d < -999999.0) | ||
| hours_d = -999999.0; |
There was a problem hiding this comment.
mlt_types.h has MIN, MAX, and CLAMP macros that should be used in multiple places in your changes to improve readability.
| @@ -0,0 +1,171 @@ | |||
| --- a/src/framework/mlt_property.c | |||
There was a problem hiding this comment.
Do not include these patch files.
|
Because I did not like your AI's style, I implemented the changes I requested in #1261 to supersede this PR. |
MLT security fixes — 2 patches
Apply from the repo root (where
CMakeLists.txtlives):(Or
patch -p1 < 0001-...patchif you're not using git.)0001 — Heap buffer overflow in
mlt_property_get_timeFile:
src/framework/mlt_property.cmlt_property_get_time()allocated a fixed 32-byte buffer and filled it viasprintf()with hours/minutes/seconds computed from an attacker-controlledframe count and frame rate (both reachable from an untrusted
.mltXMLproject file — e.g. a producer's
in/out/lengthproperty, or ananimation keyframe, combined with a profile's frame rate).
%02dis aminimum field width, not a maximum, so a large
hoursvalue (achievablewith a huge frame count and/or a very small fps) produces a string far
longer than 32 bytes, overflowing the heap allocation.
Fix:
sprintfwithsnprintfbounded by a newMLT_TIME_STRING_MAX(64 bytes) constant, so the function can never write past the buffer
regardless of input.
malloc(32)tomalloc(MLT_TIME_STRING_MAX).hours/mins/secsvalues to sane rangesbefore formatting, so degenerate/extreme inputs (e.g.
fps <= 0, or aframe count near
INT_MAX/INT_MINwith a very small fps) produce awell-formed, bounded string instead of nonsensical or wildly long output.
doublearithmetic in a couple of intermediate computations(
hours * 3600 * fps,mins * 60 * fps) that were previously done inint, which could overflow (undefined behavior) for large clampedhours/minsvalues.Verified with ASan + UBSan against a battery of extreme/adversarial inputs
(
INT_MAX/INT_MINframe counts, fps of 0, negative, near-zero, andabsurdly large) — no overflow or UB is triggered post-fix, and normal
inputs (e.g. NTSC 29.97fps) produce identical output to before.
0002 — Arbitrary command execution via
ante/postconsumer propertiesFile:
src/framework/mlt_consumer.cThe consumer's
anteandpostproperties are passed directly tosystem()when a consumer starts/stops. These properties can be setpurely by loading an
.mltXML file — a<consumer>element's attributes(or child
<property>tags) flow straight throughmlt_properties_inherit()into the real consumer's property set with nosanitization or opt-in. This means simply opening/rendering an untrusted
project file (e.g.
melt evil.mlt) can execute arbitrary shell commandswith no other action by the user.
Fix: Execution of
ante/postis now disabled by default. If eitherproperty is present but execution isn't explicitly allowed, MLT logs a
warning naming the blocked command and skips it instead of running it. An
application that intentionally wants this feature (e.g. for its own
trusted, locally-authored scripts/projects) can opt back in by setting the
environment variable:
This preserves the documented feature for users who knowingly want it,
while closing the "open a file → arbitrary code execution" path for the
common case of loading project files from an untrusted or unknown source.
Notes / things to double check before merging
MLT_CONSUMER_ANTE_POST_ALLOWEDopt-in is a minimal stopgap. If you'dprefer a different mechanism (e.g. a
mlt_consumerAPI flag theapplication sets explicitly, rather than an environment variable),
that's a reasonable alternative design — happy to rework it.
available. I did not do an exhaustive audit of the rest of the codebase
(avformat/FFmpeg integration, Qt/GDK image loaders, the
meltCLI parser,subtitle parsers, etc.) — see the earlier conversation for what was and
wasn't covered.