Skip to content

Commit

Permalink
Fixed heap-use-after-free
Browse files Browse the repository at this point in the history
  • Loading branch information
asticode committed Feb 9, 2025
1 parent 30a782d commit 6854411
Show file tree
Hide file tree
Showing 21 changed files with 138 additions and 42 deletions.
5 changes: 4 additions & 1 deletion audio_fifo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
3 changes: 3 additions & 0 deletions bit_stream_filter_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
3 changes: 3 additions & 0 deletions codec_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
4 changes: 3 additions & 1 deletion codec_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion dictionary.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 14 additions & 8 deletions filter_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
5 changes: 4 additions & 1 deletion filter_graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand All @@ -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))
}

Expand Down
4 changes: 3 additions & 1 deletion filter_graph_segment.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion filter_in_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 15 additions & 9 deletions format_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

Expand All @@ -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))
}

Expand Down Expand Up @@ -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)
}
Expand Down
4 changes: 3 additions & 1 deletion frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
File renamed without changes.
38 changes: 38 additions & 0 deletions internal/test/linux/amd64/Dockerfile
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions internal/test/linux/arm/7/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tmp
File renamed without changes.
3 changes: 3 additions & 0 deletions io_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
5 changes: 4 additions & 1 deletion io_interrupter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
4 changes: 3 additions & 1 deletion packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 13 additions & 8 deletions software_resample_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,26 @@ 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)
}
}
}

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))
}

Expand Down
23 changes: 15 additions & 8 deletions software_scale_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,28 @@ 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)
}

}
}

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))
}

Expand Down
3 changes: 3 additions & 0 deletions stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down

0 comments on commit 6854411

Please sign in to comment.