call_kernel() obtains the command buffer and compute encoder from
property getters (mtlQueue.commandBuffer, buffer.computeCommandEncoder),
which return autoreleased references under the non-ARC build, and then
releases them via ff_objc_release(). That is an over-release: when the
enclosing autorelease pool is drained, the objects are released a second
time and the process crashes with EXC_BAD_ACCESS in objc_release.
On current macOS this is reproducible with the ffmpeg CLI itself. The
filter thread's thread-local autorelease pool is popped during pthread
TSD cleanup at thread exit, so any run that used yadif_videotoolbox
crashes when the filter thread terminates:
ffmpeg -init_hw_device videotoolbox=vt -filter_hw_device vt \
-f lavfi -i testsrc2=size=640x480:rate=30 \
-vf setfield=tff,format=nv12,hwupload,yadif_videotoolbox,\
hwdownload,format=nv12 -frames:v 20 -f null -
Thread 11 Crashed:: vf#0:0
0 libobjc.A.dylib objc_release + 16
1 libobjc.A.dylib AutoreleasePoolPage::releaseUntil(objc_object**) + 204
2 libobjc.A.dylib objc_autoreleasePoolPop + 244
3 libobjc.A.dylib objc_tls_direct_base<...>::dtor_(void*) + 156
4 libsystem_pthread.dylib _pthread_tsd_cleanup + 620
5 libsystem_pthread.dylib _pthread_exit + 84
Host applications hit the same crash earlier, for example when a
dispatch queue drains its last-resort pool after a work item that ran
the filter.
Wrap the kernel invocation in @autoreleasepool and drop the manual
releases, making the pool pop the single balanced release and draining
the Metal transients once per frame. The ff_objc_release() calls on the
s->mtl* members in do_uninit() stay: those hold owned references
obtained from new* methods.
(cherry picked from commit 7f2e5cdd7c)
Limit the 8-bit column filter to the pixels remaining in the current slice. Pass slice_end - y at all three call sites so both the 8-bit and high-bit-depth column filters receive the correct remaining width. This handles partial 16-pixel blocks at frame and thread-slice boundaries. The non-column callbacks do not use this argument.
Fixes: #YWH-PGM40646-36
(cherry picked from commit 8b9e02cc17)
If s->stop is set, the return value would be overwritten
before being checked. This bug was introduced in the switch
to AV_TX in 014ace8f98.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 0992c19c30)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Reproduced with a small output (e.g. size=2x2) under ASan.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit d133b4a231)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This is a behavior preserving change for all non-overflowing cases.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit f7368f97b9)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Slice based filter workers compute their per-thread row/sample/channel
boundaries as total * jobnr / nb_jobs. The total * jobnr product is
evaluated in int and overflows signed int for large dimensions and many
slice threads, before the division by nb_jobs brings it back in range.
(cherry picked from commit 218b4771a3)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
deinterlace_slice() computed per-thread row boundaries with int
multiplication height * (jobnr + 1). With a tall frame and many filter
threads the product overflows signed int before the division by nb_jobs.
Use int64_t for the intermediate product before converting back to int
row indices.
Found-by: Kery (Qi Kery <qikeyu2001@outlook.com>)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 200e0cba67)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
For glyphs whose source is already in bitmap form (color emoji fonts such
as NotoColorEmoji.ttf), FT_Glyph_To_Bitmap(..., destroy=0) returns the
input pointer unchanged. The result is that glyph->bglyph[idx] aliases
glyph->glyph (and analogously border_bglyph[t] may alias border_glyph).
glyph_enu_free then called FT_Done_Glyph on both, double-freeing the
underlying object.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 9efca1d946)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
The code as written can add such glyphs in the cache so we need to check
glyphs from the cache too.
This should be the most robust and simple solution
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit c8c4e2d2a5)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
try_push_frame() decides whether an input buffer is already tracked by testing
`j == i` (the channel index) instead of `j == nb_buffers`. Once an earlier
channel shared a buffer, nb_buffers falls behind i and a genuinely new buffer is
never referenced, so it is freed while the output frame still points at it.
Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz Smigielski.
(cherry picked from commit 461fb22053)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: ada-2-poc.mkv
Found-by: Claude and Ada Logics. This issue was found by Anthropic from using agents to study security of open source projects, and I am from Ada Logics helping validate the found issues and report to maintainers.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 444f2cf047)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Switch to av_calloc and check the allocation.
Fix#22867
(cherry picked from commit 69072fe8d8)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
tape_length * 8 overflows 32-bit int for large input widths. Then
av_malloc_array() allocates a tiny buffer while the subsequent
loop writes tape_length*8 BilinearMap entries, causing
heap-buffer-overflow.
Validate the value in float before converting to int and left
shifting, to avoid both float-to-int and signed left shift
overflow UB. Also split av_malloc_array() arguments to avoid
the multiplication overflow.
Fixes: #21511
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
(cherry picked from commit b62ae766c1)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
GET_UTF8 advances the pointer past the newline byte before the
newline check, so shape_text_hb receives text that includes the
newline character. Since HarfBuzz does not treat U+000A as
default-ignorable, it gets shaped into a .notdef glyph.
Fixes#21565
Reported-by: scriptituk <info@scriptit.uk>
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
(cherry picked from commit fd9f1e9c52)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
The loop condition in the DEFINE_REMAP macro:
stereo < 1 + s->out_stereo > STEREO_2D
is parsed by C as:
(stereo < (1 + s->out_stereo)) > STEREO_2D
Since STEREO_2D is 0 and relational operators return 0 or 1, the
outer comparison against 0 is a no-op for STEREO_2D and STEREO_SBS.
But for STEREO_TB (value 2) the loop runs 3 iterations instead of 2,
producing an out-of-bounds stereo pass.
Add parentheses so the comparison is evaluated first:
stereo < 1 + (s->out_stereo > STEREO_2D)
This gives 1 iteration for 2D and 2 for any stereo format (SBS or TB),
matching the actual number of stereo views.
Signed-off-by: marcos ashton <marcosashiglesias@gmail.com>
(cherry picked from commit 9559a6036d)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
sscanf() returns EOF (-1) on input failure, which is non-zero and
passes a bare truthy check. When this happens, the %n directive is
never processed, so len stays uninitialized. Using that value to
advance the arg pointer causes an out-of-bounds read and crash.
Check for >= 1 instead, matching the fix applied to the other
sscanf() call in init() by commit b5b6391d64.
Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/22451
Signed-off-by: marcos ashton <marcosashiglesias@gmail.com>
(cherry picked from commit a43ea8bff7)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Why: the change is done to comply with lilv expectations of hosts.
Added call lilv_instance_activate in the config_output function to abide by lilv documentation that states it must be called before lilv_instance_run:
"This MUST be called before calling lilv_instance_run()" - documentation source (https://github.com/lv2/lilv/blob/main/include/lilv/lilv.h)
Added call lilv_instance_deactivate in the uninit function to abide by lv2 documentation:
"If a host calls activate(), it MUST call deactivate() at some point in the future" - documentation source (https://gitlab.com/lv2/lv2/-/blob/main/include/lv2/core/lv2.h)
Added instance_activated integer to LV2Context struct to track if instance was activated and only do lilv_instance_deactivate if was activated to abide by lv2 documentation:
"Hosts MUST NOT call deactivate() unless activate() was previously called." - documentation source (https://gitlab.com/lv2/lv2/-/blob/main/include/lv2/core/lv2.h)
Regarding the patcheck warning (possibly constant :instance_activated):
This is a false positive since the struct member is zero-initialized.
Fixes: trac issue #11661 (https://trac.ffmpeg.org/ticket/11661)
Reported-by: Dave Flater
Signed-off-by: Karl Mogensen <karlmogensen0@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit fa281d1394)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: signed integer overflow: 536870944 * 16 cannot be represented in type 'int'
Fixes: #21587
Found-by: HAORAN FANG
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 9adced3278)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: out of array read
Fixes: #YWH-PGM40646-35
Found-by: jpraveenrao
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 8970658472)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: out of array read
Fixes: #YWH-PGM40646-35
Found-by: jpraveenrao
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit e24b9820b4)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
In config_output() for direction=DU/RL, the position
is initialized to s->sono_size, which equals h or w
when bar=0. That position is later used as an
in-bounds pixel coordinate without clamping in draw(),
causing writes past the end of the output planes.
Repro:
ffmpeg -f lavfi -i sine=frequency=1000:sample_rate=44100 \
-filter_complex "[0:a]showcwt=s=640x512:bar=0:direction=du[v]" \
-map "[v]" -frames:v 1 -f null -
AddressSanitizer: heap-buffer-overflow ... WRITE of size 1
Initialize and wrap the DU/RL position to sono_size - 1
(or 0 when empty), preventing out-of-bounds row/column
writes when bar=0 while preserving existing slide behavior.
(cherry picked from commit 905a432403)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
We use INT32_MIN/MAX so as to ensure we dont have to deal with 64bit width or height
on a int is int64 system. int64 width would overflow in a system where we assume the product of 2
values fit in int64
Fixes: #YWH-PGM40646-14
Found-by: An0n99X
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 805931dfc8)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: out of array read
Fixes: #YWH-PGM40646-17
Found-by: An0n99X
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit f99df7dbb3)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This cannot really happen, but to suppress compiler warnings, we can
just return AVERROR_BUG here.
Fixes: warning: variable 'kernel_name' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
(cherry picked from commit 1fa5e001bc)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: warning: 'sscanf' may overflow; destination buffer in argument 7 has size 32, but the corresponding specifier may require size 33 [-Wfortify-source]
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
(cherry picked from commit cca872b6fd)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
And free them once they are guaranteed to be no longer needed, instead of freeing them
when returned with an enhanced output.
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit af136db1c3)
The check if a native layout can be created from the sources was incomplete and
casued a crash with custom layouts if the layout contained a native channel
multiple times, as in this example command line:
ffmpeg -lavfi "sine[a0];sine,pan=FL+FL[a1];[a0][a1]amerge[aout]" -map "[aout]" -t 1 -f framecrc -
Signed-off-by: Marton Balint <cus@passwd.hu>
(cherry picked from commit e8b10a9b09)
There is currently no way for API users to know that a buffersrc is no longer
accepting input, except by trying to feed it a frame and seeing what happens.
Of course, this is not possible if the user does not *have* a frame to feed,
but may still wish to know if the filter is still accepting input or not.
Since passing `frame == NULL` to `av_buffersrc_add_frame()` is already treated
as closing the input, we are left with no choice but to introduce a new
function for this.
We don't explicitly return the result of `ff_outlink_get_status()` to avoid
leaking internal status codes, and instead translate them all to AVERROR(EOF).
Backported-from: 623669a02c