Skip to content

Buffer overflows when handling files with path longer than PATH_MAX #232

@SouthCraftX

Description

@SouthCraftX

TL;DR
wavpack crashes with a 0xc0000409 (FAST_FAIL_RANGE_CHECK_FAILURE) at the very end of the encoding process if the output absolute path exceeds PATH_MAX.

I'm using Wavpack 5.9.0 from MSYS2 UCRT64

wavpack --version
wavpack 5.9.0
libwavpack 5.9.0

My command line:

"C:\msys64\ucrt64\bin\wavpack.exe" -hh -x6 -m -v "D:\BaiduNetdiskDownload\_初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」(2023)[wav]{flyingDOG}\初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」(2023)[wav]{flyingDOG}\Various Artists - 初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」.wav" -o "D:\BaiduNetdiskDownload\_初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」(2023)[wav]{flyingDOG}\初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」(2023)[wav]{flyingDOG}\Various Artists - 初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」.wv"

It crashed when conversion was almost done:


 WAVPACK  Hybrid Lossless Audio Compressor  Win64 Version 5.9.0
 Copyright (c) 1998 - 2026 David Bryant.  All Rights Reserved.

overwrite Various Artists - 初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」.wv (yes/no/all)? y
creating Various Artists - 初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」.wv, 100% done...*** buffer overflow detected ***: terminated

I checked the wv file wasn't corrupted and was bit-perfect compared to original audio.

GDB Logs:

[Switching to Thread 27444.0x1370]
0x00007ff7b09d5717 in ?? ()
(gdb) bt
#0  0x00007ff7b09d5717 in ?? ()
#1  0x00007ff7b09d583a in ?? ()
#2  0x00007ff7b09c8ae8 in ?? ()
#3  0x00007ff7b09cb990 in ?? ()
#4  0x00007ff7b09df78b in ?? ()
#5  0x00007ff7b09c10d9 in ?? ()
#6  0x00007ff7b09c1456 in ?? ()
#7  0x00007ffe3918e8d7 in KERNEL32!BaseThreadInitThunk () from C:\Windows\System32\kernel32.dll
#8  0x00007ffe3a18c40c in ntdll!RtlUserThreadStart () from C:\Windows\SYSTEM32\ntdll.dll
#9  0x0000000000000000 in ?? ()
(gdb) x/20s $rsp
0x56493fefd0:   "`\374L\372\377\001"
0x56493fefd7:   ""
0x56493fefd8:   "\373\340\3237\376\177"
0x56493fefdf:   ""
0x56493fefe0:   ""
0x56493fefe1:   ""
0x56493fefe2:   ""
0x56493fefe3:   ""
0x56493fefe4:   ""
0x56493fefe5:   ""
0x56493fefe6:   ""
0x56493fefe7:   ""
0x56493fefe8:   ""
0x56493fefe9:   ""
0x56493fefea:   ""
0x56493fefeb:   ""
0x56493fefec:   ""
0x56493fefed:   ""
0x56493fefee:   ""
0x56493fefef:   ""
(gdb) x/32gx $rsp
0x56493fefd0:   0x000001fffa4cfc60      0x00007ffe37d3e0fb
0x56493fefe0:   0x0000000000000000      0x0000000000000000
0x56493feff0:   0x00000056493ff164      0x00007ff7b09d583a
0x56493ff000:   0x000001fffa4e03e0      0x000001fffa52a5b0
0x56493ff010:   0x0000000000000000      0x00007ffe37d3e0fb
0x56493ff020:   0x000001fffa4c0000      0x000001fffa4e0150
0x56493ff030:   0x000001fffa4e03e0      0x0000000000000000
0x56493ff040:   0x000001fffa52a5b0      0x00007ff7b09c8ae8
0x56493ff050:   0x0000000000010000      0x00007ff700000000
0x56493ff060:   0x00007ff7000639c0      0x0000000000000062
0x56493ff070:   0x00000056493ff1d0      0x000000000000001c
0x56493ff080:   0x0000000000000000      0x00000000e50000e5
0x56493ff090:   0x0000000000000000      0x000001fffa4e0150
0x56493ff0a0:   0x000001fffa4d0940      0x0000000000000000
0x56493ff0b0:   0x000001fffa4e03e0      0x0000000000000000
0x56493ff0c0:   0x000001fffa4cff50      0x0000000000000004
(gdb) x/20i 0x00007ff7b09d583a - 0x30
   0x7ff7b09d580a:      mov    %edx,%ecx
   0x7ff7b09d580c:      mov    %rdx,0x28(%rsp)
   0x7ff7b09d5811:      mov    %r8,%rbx
   0x7ff7b09d5814:      call   0x7ff7b09df330
   0x7ff7b09d5819:      mov    0x28(%rsp),%rdx
   0x7ff7b09d581e:      cmp    %rbx,%rax
   0x7ff7b09d5821:      jae    0x7ff7b09d5835
   0x7ff7b09d5823:      lea    0x1(%rax),%r8
   0x7ff7b09d5827:      mov    %rsi,%rcx
   0x7ff7b09d582a:      add    $0x38,%rsp
   0x7ff7b09d582e:      pop    %rbx
   0x7ff7b09d582f:      pop    %rsi
   0x7ff7b09d5830:      jmp    0x7ff7b09df4d8
   0x7ff7b09d5835:      call   0x7ff7b09d56e0
   0x7ff7b09d583a:      nop
   0x7ff7b09d583b:      nop
   0x7ff7b09d583c:      nop
   0x7ff7b09d583d:      nop
   0x7ff7b09d583e:      nop
   0x7ff7b09d583f:      nop
(gdb) info registers
rax            0x1                 1
rbx            0x104               260
rcx            0x8                 8
rdx            0x1fffa350000       2198926065664
rsi            0x56493ff300        370596115200
rdi            0x1fffa4e03e0       2198927705056
rbp            0x0                 0x0
rsp            0x56493fefd0        0x56493fefd0
r8             0x7ffffffffffffffc  9223372036854775804
r9             0x0                 0
r10            0x0                 0
r11            0x56493fee30        370596113968
r12            0x1fffa4e5180       2198927724928
r13            0x56493ff164        370596114788
r14            0x0                 0
r15            0x0                 0
rip            0x7ff7b09d5717      0x7ff7b09d5717
eflags         0x202               [ IF ]
cs             0x33                51
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x53                83
gs             0x2b                43
(gdb) x/s 0x000001fffa4e03e0
0x1fffa4e03e0:  "\220\372L\372\377\001"
(gdb) x/s 0x000001fffa52a5b0
0x1fffa52a5b0:  ""
(gdb) x/s 0x000001fffa4c0000
0x1fffa4c0000:  ""
(gdb) x/s 0x000001fffa4e0150
0x1fffa4e0150:  "D:\\BaiduNetdiskDownload\\_初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」(2023)[wav]{flyingDOG}\\初音ミク「マジカルミライ」10周年記念コ"...
(gdb) x/s 0x000001fffa4cfc60
0x1fffa4cfc60:  "D"
(gdb) x/40i 0x00007ff7b09d583a - 0x60
   0x7ff7b09d57da:      test   %r8,%r8
   0x7ff7b09d57dd:      je     0x7ff7b09d57ed
   0x7ff7b09d57df:      movb   $0x0,(%rax)
   0x7ff7b09d57e2:      mov    %rdi,%rax
   0x7ff7b09d57e5:      add    $0x20,%rsp
   0x7ff7b09d57e9:      pop    %rbx
   0x7ff7b09d57ea:      pop    %rsi
   0x7ff7b09d57eb:      pop    %rdi
   0x7ff7b09d57ec:      ret
   0x7ff7b09d57ed:      call   0x7ff7b09d56e0
   0x7ff7b09d57f2:      nop
   0x7ff7b09d57f3:      nop
   0x7ff7b09d57f4:      nop
   0x7ff7b09d57f5:      nop
   0x7ff7b09d57f6:      nop
   0x7ff7b09d57f7:      nop
   0x7ff7b09d57f8:      nop
   0x7ff7b09d57f9:      nop
   0x7ff7b09d57fa:      nop
   0x7ff7b09d57fb:      nop
   0x7ff7b09d57fc:      nop
   0x7ff7b09d57fd:      nop
   0x7ff7b09d57fe:      nop
   0x7ff7b09d57ff:      nop
   0x7ff7b09d5800:      push   %rsi
   0x7ff7b09d5801:      push   %rbx
   0x7ff7b09d5802:      sub    $0x38,%rsp
   0x7ff7b09d5806:      mov    %rcx,%rsi
   0x7ff7b09d5809:      mov    %rdx,%rcx
--Type <RET> for more, q to quit, c to continue without paging--c
   0x7ff7b09d580c:      mov    %rdx,0x28(%rsp)
   0x7ff7b09d5811:      mov    %r8,%rbx
   0x7ff7b09d5814:      call   0x7ff7b09df330
   0x7ff7b09d5819:      mov    0x28(%rsp),%rdx
   0x7ff7b09d581e:      cmp    %rbx,%rax
   0x7ff7b09d5821:      jae    0x7ff7b09d5835
   0x7ff7b09d5823:      lea    0x1(%rax),%r8
   0x7ff7b09d5827:      mov    %rsi,%rcx
   0x7ff7b09d582a:      add    $0x38,%rsp
   0x7ff7b09d582e:      pop    %rbx
   0x7ff7b09d582f:      pop    %rsi
(gdb) set print elements 0
(gdb) x/s 0x000001fffa4e0150
0x1fffa4e0150:  "D:\\BaiduNetdiskDownload\\_初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」(2023)[wav]{flyingDOG}\\初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」(2023)[wav]{flyingDOG}\\Various Artists - 初音ミク「マジカルミライ」10周年記念コンピレーション「MIRACLE SONGS」.wv"
(gdb) x/15i 0x00007ff7b09c8ae8 - 0x24
   0x7ff7b09c8ac4:      rex.R and $0x48,%al
   0x7ff7b09c8ac7:      cmpb   $0x2d,(%rax)
   0x7ff7b09c8aca:      je     0x7ff7b09c8b5d
   0x7ff7b09c8ad0:      mov    0x48(%rsp),%rdx
   0x7ff7b09c8ad5:      mov    $0x104,%r8d
   0x7ff7b09c8adb:      lea    0x2b0(%rsp),%rcx
   0x7ff7b09c8ae3:      call   0x7ff7b09d5800
   0x7ff7b09c8ae8:      lea    0x1892f(%rip),%rdx        # 0x7ff7b09e141e
   0x7ff7b09c8aef:      lea    0x2b0(%rsp),%rcx
   0x7ff7b09c8af7:      mov    $0x104,%r8d
   0x7ff7b09c8afd:      call   0x7ff7b09d5780
   0x7ff7b09c8b02:      lea    0x1853f(%rip),%rdx        # 0x7ff7b09e1048
   0x7ff7b09c8b09:      lea    0x2b0(%rsp),%rcx
   0x7ff7b09c8b11:      call   0x7ff7b09d41d0
   0x7ff7b09c8b16:      test   %rax,%rax
(gdb) x/s 0x7ff7b09e141e
0x7ff7b09e141e: "c"
(gdb) x/s 0x7ff7b09e1048
0x7ff7b09e1048: "rb"
(gdb) u 0x7ff7b09d41d0
Function "0x7ff7b09d41d0" not defined.
(gdb) info import
Undefined info command: "import".  Try "help info".
(gdb) dps wavpack+0x2d820
Undefined command: "dps".  Try "help".
(gdb) x/16s 0x7ff7b09e1410
0x7ff7b09e1410: "ource file %s"
0x7ff7b09e141e: "c"
0x7ff7b09e1420: "can not remove file %s, result saved in %s!"
0x7ff7b09e144c: ""
0x7ff7b09e144d: ""
0x7ff7b09e144e: ""
0x7ff7b09e144f: ""
0x7ff7b09e1450: "can not rename temp file %s to %s!"
0x7ff7b09e1473: ""
0x7ff7b09e1474: ""
0x7ff7b09e1475: ""
0x7ff7b09e1476: ""
0x7ff7b09e1477: ""
0x7ff7b09e1478: "%s obsolete correction file %s"
0x7ff7b09e1497: ""
0x7ff7b09e1498: "ave noise = %.2f dB, peak noise = %.2f dB"
(gdb) x/16s 0x7ff7b09e1040
0x7ff7b09e1040: "avPack)"
0x7ff7b09e1048: "rb"
0x7ff7b09e104b: "^C\n"
0x7ff7b09e104f: '\b' <repeats 12 times>
0x7ff7b09e105c: "%s%3d%% done..."
0x7ff7b09e106c: "%02x"
0x7ff7b09e1071: "original md5: %s"
0x7ff7b09e1082: "verified md5: %s"
0x7ff7b09e1093: ""
0x7ff7b09e1094: ""
0x7ff7b09e1095: ""
0x7ff7b09e1096: ""
0x7ff7b09e1097: ""
0x7ff7b09e1098: "MD5 signatures should match, but do not!"
0x7ff7b09e10c1: "file is missing %llu samples!"
0x7ff7b09e10df: "file has %llu extra samples!"

0x104 refers to PATH_MAX
Continuing investigating, I found this suspicious source code:
In wavpack.c:

    if (!out2filename && outfilename && *outfilename != '-') {
        char out2filename_obsolete [PATH_MAX];
        FILE *testfile;
        int res;

        strcpy (out2filename_obsolete, outfilename);
        strcat (out2filename_obsolete, "c");

        if ((testfile = fopen (out2filename_obsolete, "rb")) != NULL) {
            fclose (testfile);
            res = DoDeleteFile (out2filename_obsolete);

            if (!quiet_mode || !res)
                error_line ("%s obsolete correction file %s",
                    res ? "deleted" : "can't delete", out2filename_obsolete);
        }
    }

It seems that compiler inserted stack protection code inside strcpy or strcat.
out2filename_obsolete should be from malloc() or large enough (maybe 64k)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions