Fixed heap-use-after-free

This commit is contained in:
Quentin Renard
2025-02-09 15:08:47 +01:00
parent 30a782ddf4
commit 685441141d
21 changed files with 138 additions and 42 deletions

View File

@@ -56,5 +56,8 @@ func (a *AudioFifo) Read(f *Frame) (int, error) {
// https://ffmpeg.org/doxygen/7.0/group__lavu__audiofifo.html#ga74e029e47f7aa99217ad1f315c434875
func (a *AudioFifo) Free() {
C.av_audio_fifo_free(a.c)
if a.c != nil {
C.av_audio_fifo_free(a.c)
a.c = nil
}
}

View File

@@ -39,6 +39,9 @@ func AllocBitStreamFilterContext(f *BitStreamFilter) (*BitStreamFilterContext, e
// https://ffmpeg.org/doxygen/7.0/structAVBSFContext.html#aa5d5018816daac804414c459ec8a1c5c
func (bsfc *BitStreamFilterContext) Class() *Class {
if bsfc.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(bsfc.c))
}

View File

@@ -89,6 +89,9 @@ func (cc *CodecContext) ChromaLocation() ChromaLocation {
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a90622d3af2a9abba986a1c9f7ca21b16
func (cc *CodecContext) Class() *Class {
if cc.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(cc.c))
}

View File

@@ -22,7 +22,9 @@ func newCodecParametersFromC(c *C.AVCodecParameters) *CodecParameters {
// https://ffmpeg.org/doxygen/7.0/group__lavc__core.html#ga950c8da55b8112077e640b6a0cb8cf36
func (cp *CodecParameters) Free() {
C.avcodec_parameters_free(&cp.c)
if cp.c != nil {
C.avcodec_parameters_free(&cp.c)
}
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecParameters.html#a5268fcf4ae8ed27edef54f836b926d93

View File

@@ -60,7 +60,9 @@ func (d *Dictionary) Get(key string, prev *DictionaryEntry, flags DictionaryFlag
// https://ffmpeg.org/doxygen/7.0/group__lavu__dict.html#ga1bafd682b1fbb90e48a4cc3814b820f7
func (d *Dictionary) Free() {
C.av_dict_free(&d.c)
if d.c != nil {
C.av_dict_free(&d.c)
}
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__packet.html#ga2d2c8e143a2c98cf0aa31b072c286186

View File

@@ -24,19 +24,25 @@ var _ Classer = (*FilterContext)(nil)
// https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga0ea7664a3ce6bb677a830698d358a179
func (fc *FilterContext) Free() {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(fc)
C.avfilter_free(fc.c)
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
if fc.c != nil {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(fc)
C.avfilter_free(fc.c)
fc.c = nil
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
}
}
}
// https://ffmpeg.org/doxygen/7.0/structAVFilterContext.html#a00ac82b13bb720349c138310f98874ca
func (fc *FilterContext) Class() *Class {
if fc.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(fc.c))
}

View File

@@ -37,7 +37,7 @@ func (g *FilterGraph) Free() {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(g)
var cfcs []Classer
var cfcs []*ClonedClasser
for _, fc := range g.fcs {
cfcs = append(cfcs, newClonedClasser(fc))
}
@@ -62,6 +62,9 @@ func (g *FilterGraph) String() string {
// https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#af00925dd69b474fac48887efc0e1ac94
func (g *FilterGraph) Class() *Class {
if g.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(g.c))
}

View File

@@ -21,7 +21,9 @@ func newFilterGraphSegmentFromC(c *C.AVFilterGraphSegment) *FilterGraphSegment {
// https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga51283edd8f3685e1f33239f360e14ae8
func (fgs *FilterGraphSegment) Free() {
C.avfilter_graph_segment_free(&fgs.c)
if fgs.c != nil {
C.avfilter_graph_segment_free(&fgs.c)
}
}
// https://ffmpeg.org/doxygen/7.0/structAVFilterGraphSegment.html#ad5a2779af221d1520490fe2719f9e39a

View File

@@ -22,7 +22,9 @@ func AllocFilterInOut() *FilterInOut {
// https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga294500a9856260eb1552354fd9d9a6c4
func (i *FilterInOut) Free() {
C.avfilter_inout_free(&i.c)
if i.c != nil {
C.avfilter_inout_free(&i.c)
}
}
// https://ffmpeg.org/doxygen/7.0/structAVFilterInOut.html#a88afecac258f51aab7e9a9db9e7a4d58

View File

@@ -55,14 +55,17 @@ func AllocOutputFormatContext(of *OutputFormat, formatName, filename string) (*F
// https://ffmpeg.org/doxygen/7.0/group__lavf__core.html#gac2990b13b68e831a408fce8e1d0d6445
func (fc *FormatContext) Free() {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(fc)
C.avformat_free_context(fc.c)
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
if fc.c != nil {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(fc)
C.avformat_free_context(fc.c)
fc.c = nil
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
}
}
}
@@ -73,6 +76,9 @@ func (fc *FormatContext) BitRate() int64 {
// https://ffmpeg.org/doxygen/7.0/structAVFormatContext.html#a0c396740b9a2487aa57d4352d2dc1687
func (fc *FormatContext) Class() *Class {
if fc.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(fc.c))
}
@@ -238,7 +244,7 @@ func (fc *FormatContext) CloseInput() {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(fc)
var cpb Classer
var cpb *ClonedClasser
if pb := fc.Pb(); pb != nil {
cpb = newClonedClasser(pb)
}

View File

@@ -266,7 +266,9 @@ func (f *Frame) TransferHardwareData(dst *Frame) error {
// https://ffmpeg.org/doxygen/7.0/group__lavu__frame.html#ga979d73f3228814aee56aeca0636e37cc
func (f *Frame) Free() {
C.av_frame_free(&f.c)
if f.c != nil {
C.av_frame_free(&f.c)
}
}
// https://ffmpeg.org/doxygen/7.0/group__lavu__frame.html#ga88b0ecbc4eb3453eef3fbefa3bddeb7c

View File

@@ -0,0 +1,38 @@
FROM amd64/debian:12.5
RUN apt-get update
RUN apt-get install -y \
build-essential \
git \
pkg-config \
yasm \
libpng-dev
RUN \
mkdir -p /opt/ffmpeg/src
WORKDIR /opt/ffmpeg/src
RUN \
git clone https://github.com/FFmpeg/FFmpeg /opt/ffmpeg/src && \
git checkout n7.0
RUN \
./configure --prefix=.. && \
make && \
make install
ADD https://dl.google.com/go/go1.22.0.linux-amd64.tar.gz /tmp/go.tar.gz
RUN tar -C /opt -xzf /tmp/go.tar.gz
ENV GOCACHE=/opt/gocache
ENV GOMODCACHE=/opt/gomodcache
ENV CGO_LDFLAGS=-L/opt/ffmpeg/lib/
ENV CGO_CFLAGS=-I/opt/ffmpeg/include/
ENV PKG_CONFIG_PATH=/opt/ffmpeg/lib/pkgconfig
ENV CGO_ENABLED=1
WORKDIR /opt/astiav
CMD ["/opt/go/bin/go", "test", "-asan"]

1
internal/test/linux/arm/7/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
tmp

View File

@@ -128,6 +128,9 @@ func OpenIOContext(filename string, flags IOContextFlags, ii *IOInterrupter, d *
}
func (ic *IOContext) Class() *Class {
if ic.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(ic.c))
}

View File

@@ -17,7 +17,10 @@ func NewIOInterrupter() *IOInterrupter {
}
func (i *IOInterrupter) Free() {
C.free(unsafe.Pointer(i.c))
if i.c != nil {
C.free(unsafe.Pointer(i.c))
i.c = nil
}
}
func (i *IOInterrupter) Interrupt() {

View File

@@ -112,7 +112,9 @@ func (p *Packet) SetStreamIndex(i int) {
// https://ffmpeg.org/doxygen/7.0/group__lavc__packet.html#ga1066464e7cdd1f215df6940db94e5d8e
func (p *Packet) Free() {
C.av_packet_free(&p.c)
if p.c != nil {
C.av_packet_free(&p.c)
}
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__packet.html#gacbe3e51cf411a7003d706127dc48cbb1

View File

@@ -25,14 +25,16 @@ func AllocSoftwareResampleContext() *SoftwareResampleContext {
// https://ffmpeg.org/doxygen/7.0/group__lswr.html#ga818f7d78b1ad7d8d5b70de374b668c34
func (src *SoftwareResampleContext) Free() {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(src)
C.swr_free(&src.c)
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
if src.c != nil {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(src)
C.swr_free(&src.c)
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
}
}
}
@@ -40,6 +42,9 @@ var _ Classer = (*SoftwareResampleContext)(nil)
// https://ffmpeg.org/doxygen/7.0/structSwrContext.html#a7e13adcdcbc11bcc933cb7d0b9f839a0
func (src *SoftwareResampleContext) Class() *Class {
if src.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(src.c))
}

View File

@@ -62,14 +62,18 @@ func CreateSoftwareScaleContext(srcW, srcH int, srcFormat PixelFormat, dstW, dst
// https://ffmpeg.org/doxygen/7.0/group__libsws.html#gad3af0ca76f071dbe0173444db9882932
func (ssc *SoftwareScaleContext) Free() {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(ssc)
C.sws_freeContext(ssc.c)
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
if ssc.c != nil {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(ssc)
C.sws_freeContext(ssc.c)
ssc.c = nil
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
}
}
}
@@ -77,6 +81,9 @@ var _ Classer = (*SoftwareScaleContext)(nil)
// https://ffmpeg.org/doxygen/7.0/structSwsContext.html#a6866f52574bc730833d2580abc806261
func (ssc *SoftwareScaleContext) Class() *Class {
if ssc.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(ssc.c))
}

View File

@@ -28,6 +28,9 @@ func (s *Stream) SetAvgFrameRate(r Rational) {
// https://ffmpeg.org/doxygen/7.0/structAVStream.html#a4737d8b012827558f55a6f559b253496
func (s *Stream) Class() *Class {
if s.c == nil {
return nil
}
return newClassFromC(unsafe.Pointer(s.c))
}