audiofile
audiofile copied to clipboard
NULL pointer dereference bug in ulaw2linear_buf, in G711.cpp
There exists one NULL pointer dereference bug in ulaw2linear_buf, in G711.cpp, which allows an attacker to cause a denial of service via a crafted file. To reproduce with the attached poc file: ./sfconvert poc output format voc poc.zip
gdb output
[----------------------------------registers-----------------------------------]
RAX: 0xffff8284
RBX: 0x0
RCX: 0x7
RDX: 0x7e00 ('')
RSI: 0x7d7c ('|}')
RDI: 0xffffffff
RBP: 0x7fffebce2010 --> 0x0
RSP: 0x7fffffffe2a0 --> 0x7ffff7b20ef6 (<afGetFrameCount(AFfilehandle, int)+390>: mov rax,QWORD PTR [rsp+0x10])
RIP: 0x7ffff7b388bf (<G711::runPull()+3199>: mov WORD PTR [rbx+r12*2],ax)
R8 : 0x0
R9 : 0x55555576b648 --> 0x0
R10: 0x55555576af48 --> 0x3e9
R11: 0x246
R12: 0x0
R13: 0x0
R14: 0x1
R15: 0x55555576b120 --> 0x7ffff7dd3568 --> 0x7ffff7b39440 (<G711::~G711()>: lea rsp,[rsp-0x98])
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x7ffff7b388ac <G711::runPull()+3180>: lea rsp,[rsp+0x98]
0x7ffff7b388b4 <G711::runPull()+3188>: movzx edi,BYTE PTR [rbp+r12*1+0x0]
0x7ffff7b388ba <G711::runPull()+3194>: call 0x7ffff7b23370 <_af_ulaw2linear>
=> 0x7ffff7b388bf <G711::runPull()+3199>: mov WORD PTR [rbx+r12*2],ax
0x7ffff7b388c4 <G711::runPull()+3204>: add r12,0x1
0x7ffff7b388c8 <G711::runPull()+3208>: cmp QWORD PTR [rsp+0x10],r12
0x7ffff7b388cd <G711::runPull()+3213>: je 0x7ffff7b38348 <G711::runPull()+1800>
0x7ffff7b388d3 <G711::runPull()+3219>: nop
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe2a0 --> 0x7ffff7b20ef6 (<afGetFrameCount(AFfilehandle, int)+390>: mov rax,QWORD PTR [rsp+0x10])
0008| 0x7fffffffe2a8 --> 0x0
0016| 0x7fffffffe2b0 --> 0x61616161 ('aaaa')
0024| 0x7fffffffe2b8 --> 0x7ffff7b1ae32 (<afReadFrames(AFfilehandle, int, void*, int)+34>: mov rax,QWORD PTR [rsp+0x10])
0032| 0x7fffffffe2c0 --> 0x0
0040| 0x7fffffffe2c8 --> 0x1
0048| 0x7fffffffe2d0 --> 0x55555576b360 --> 0x7fff00000003
0056| 0x7fffffffe2d8 --> 0x55555576af48 --> 0x3e9
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00007ffff7b388bf in ulaw2linear_buf (nsamples=<optimized out>, linear=<optimized out>, ulaw=<optimized out>) at G711.cpp:42
42 linear[i] = _af_ulaw2linear(ulaw[i]);
gdb-peda$ bt
#0 0x00007ffff7b388bf in ulaw2linear_buf (nsamples=<optimized out>, linear=<optimized out>, ulaw=<optimized out>) at G711.cpp:42
#1 G711::runPull (this=0x55555576b120) at G711.cpp:206
#2 0x00007ffff7b1b4b6 in afReadFrames (file=<optimized out>, trackid=<optimized out>, samples=0x0, nvframeswanted=<optimized out>) at data.cpp:222
#3 0x0000555555555f9e in copyaudiodata (infile=0x55555576ae90, outfile=0x55555576b6c0, trackid=0x3e9) at sfconvert.c:340
#4 0x00005555555555e1 in main (argc=argc@entry=0x5, argv=argv@entry=0x7fffffffe508) at sfconvert.c:248
#5 0x00007ffff76f3b97 in __libc_start_main (main=0x555555555370 <main>, argc=0x5, argv=0x7fffffffe508, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe4f8) at ../csu/libc-start.c:310
#6 0x0000555555555c3a in _start ()
caused by allocate too large mem, and then alloc return 0
asan output
root@ubuntu:~/audiofile-santi/sfcommands/.libs# ./sfconvert /home/tim/poc output format voc
==129695==WARNING: AddressSanitizer failed to allocate 0xffffffffc2c00000 bytes
==129695==AddressSanitizer's allocator is terminating the process instead of returning 0
==129695==If you don't like this behavior set allocator_may_return_null=1
==129695==AddressSanitizer CHECK failed: ../../../../src/libsanitizer/sanitizer_common/sanitizer_allocator.cc:218 "((0)) != (0)" (0x0, 0x0)
#0 0x7f48c8503c02 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe9c02)
#1 0x7f48c8522595 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x108595)
#2 0x7f48c8509342 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xef342)
#3 0x7f48c8441e46 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x27e46)
#4 0x7f48c84f8b1a in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb1a)
#5 0x558dc209af68 in copyaudiodata /home/tim/audiofile-santi/sfcommands/sfconvert.c:327
#6 0x558dc209a620 in main /home/tim/audiofile-santi/sfcommands/sfconvert.c:248
#7 0x7f48c7d38b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#8 0x558dc209ac79 in _start (/home/tim/audiofile-santi/sfcommands/.libs/sfconvert+0x1c79)
CVE-2019-13147 was assigned for this issue.
For completeness, this is the stacktrace I get with the provided poc:
==6157==WARNING: AddressSanitizer failed to allocate 0xffffffff85858580 bytes
AddressSanitizer:DEADLYSIGNAL
=================================================================
==6157==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f68322200db bp 0x7f6824545800 sp 0x7ffd57f71660 T0)
==6157==The signal is caused by a WRITE memory access.
==6157==Hint: address points to the zero page.
#0 0x7f68322200db in ulaw2linear_buf(unsigned char const*, short*, int) /var/tmp/portage/media-libs/audiofile-0.3.6-r5/work/audiofile-0.3.6/libaudiofile/modules/G711.cpp:42:13
#1 0x7f68322200db in G711::runPull() /var/tmp/portage/media-libs/audiofile-0.3.6-r5/work/audiofile-0.3.6/libaudiofile/modules/G711.cpp:206:3
#2 0x7f6832212ec1 in afReadFrames /var/tmp/portage/media-libs/audiofile-0.3.6-r5/work/audiofile-0.3.6/libaudiofile/data.cpp:222:14
#3 0x4f42e1 in copyaudiodata /var/tmp/portage/media-libs/audiofile-0.3.6-r5/work/audiofile-0.3.6/sfcommands/sfconvert.c:370:29
#4 0x4f3b57 in main /var/tmp/portage/media-libs/audiofile-0.3.6-r5/work/audiofile-0.3.6/sfcommands/sfconvert.c:275:17
#5 0x7f6831f31676 in __libc_start_call_main /var/tmp/portage/sys-libs/glibc-2.37-r3/work/glibc-2.37/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#6 0x7f6831f31734 in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.37-r3/work/glibc-2.37/csu/../csu/libc-start.c:360:3
#7 0x41e780 (/usr/bin/sfconvert+0x41e780)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /var/tmp/portage/media-libs/audiofile-0.3.6-r5/work/audiofile-0.3.6/libaudiofile/modules/G711.cpp:42:13 in ulaw2linear_buf(unsigned char const*, short*, int)
==6157==ABORTING
Aborted
While the asan output complains about " failed to allocate" I confirm that under normal condition I get a Segmentation fault.
Partial fix (symptom), nevertheless a fix:
commit 2f762fa2dd93fe2c66c59150d89ed15778274690
Author: Bastien Roucariès <[email protected]>
Date: Sat Nov 11 17:42:03 2023 +0000
Partial fix of CVE-2019-13147
This fix the symptom do not allow to allocate negative memory:
==129695==WARNING: AddressSanitizer failed to allocate 0xffffffffc2c00000 bytes
==129695==AddressSanitizer's allocator is terminating the process instead of returning 0
==129695==If you don't like this behavior set allocator_may_return_null=1
==129695==AddressSanitizer CHECK failed: ../../../../src/libsanitizer/sanitizer_common/sanitizer_allocator.cc:218 "((0)) != (0)" (0x0, 0x0)
#0 0x7f48c8503c02 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe9c02)
#1 0x7f48c8522595 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x108595)
#2 0x7f48c8509342 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xef342)
#3 0x7f48c8441e46 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x27e46)
#4 0x7f48c84f8b1a in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb1a)
#5 0x558dc209af68 in copyaudiodata /home/tim/audiofile-santi/sfcommands/sfconvert.c:327
#6 0x558dc209a620 in main /home/tim/audiofile-santi/sfcommands/sfconvert.c:248
#7 0x7f48c7d38b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#8 0x558dc209ac79 in _start (/home/tim/audiofile-santi/sfcommands/.libs/sfconvert+0x1c79)
If negative bail out
diff --git a/sfcommands/sfconvert.c b/sfcommands/sfconvert.c
index 367f7a5..400d485 100644
--- a/sfcommands/sfconvert.c
+++ b/sfcommands/sfconvert.c
@@ -349,7 +349,8 @@ void printversion (void)
bool copyaudiodata (AFfilehandle infile, AFfilehandle outfile, int trackid)
{
int frameSize = afGetVirtualFrameSize(infile, trackid, 1);
-
+ if(frameSize <= 0)
+ return false;
int kBufferFrameCount = 65536;
int bufferSize;
while (multiplyCheckOverflow(kBufferFrameCount, frameSize, &bufferSize))
Real fix is too many channel:
commit 18e39112376f488bf57ca6527d42afc644f06a94 (HEAD -> patch-queue/master)
Author: Bastien Roucariès <[email protected]>
Date: Sat Nov 11 17:43:19 2023 +0000
Partial fix of CVE-2019-13147
This is the fix of the POC. Do not allow too many channel
Now it fail with:
Audio File Library: invalid file with 1633771873 channels [error 15]
Could not open file 'poc' for reading.
diff --git a/libaudiofile/NeXT.cpp b/libaudiofile/NeXT.cpp
index c462dbe..01c967c 100644
--- a/libaudiofile/NeXT.cpp
+++ b/libaudiofile/NeXT.cpp
@@ -32,6 +32,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include "File.h"
#include "Setup.h"
@@ -122,6 +123,12 @@ status NeXTFile::readInit(AFfilesetup setup)
_af_error(AF_BAD_CHANNELS, "invalid file with 0 channels");
return AF_FAIL;
}
+ /* avoid overflow of INT for double size rate */
+ if (channelCount > (INT32_MAX / (sizeof(double))))
+ {
+ _af_error(AF_BAD_CHANNELS, "invalid file with %i channels", channelCount);
+ return AF_FAIL;
+ }
Track *track = allocateTrack();
if (!track)