This is My proposed Fix
Proposed Fix for libavformat/vpk.c
C

static int vpk_read_header(AVFormatContext *s){
    VPKDemuxContext *vpk = s->priv_data;
    unsigned offset;
    AVStream *st;
    int samples_per_block;

    vpk->last_block_size = 0;
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    avio_skip(s->pb, 4); // Skip "VPK " magic
    offset = avio_rl32(s->pb);
    avio_skip(s->pb, 4);
    st->duration = avio_rl32(s->pb);

    /* FIX: Validate sample rate and channel count to prevent division
by zero */
    st->codecpar->sample_rate = avio_rl32(s->pb);
    st->codecpar->ch_layout.nb_channels = avio_rl32(s->pb);

    if (st->codecpar->sample_rate <= 0 ||
st->codecpar->ch_layout.nb_channels <= 0) {
        av_log(s, AV_LOG_ERROR, "Invalid sample rate (%d) or channel
count (%d)\n",
               st->codecpar->sample_rate, st->codecpar->ch_layout.nb_channels);
        return AVERROR_INVALIDDATA;
    }

    // ... (rest of header parsing) ...

    /* FIX: Ensure samples_per_block is positive before calculation */
    samples_per_block = (vpk->block_size - 16 *
st->codecpar->ch_layout.nb_channels) * 2 /
                         st->codecpar->ch_layout.nb_channels;

    if (samples_per_block <= 0) {
        av_log(s, AV_LOG_ERROR, "Invalid block size or channel count
resulting in non-positive samples per block\n");
        return AVERROR_INVALIDDATA;
    }

    vpk->block_count = (st->duration + (samples_per_block - 1)) /
samples_per_block;

    return 0;
}

------------------------------
Why this works:

   1.

   *Immediate Return:* By checking sample_rate and nb_channels immediately
   after they are read from avio_rl32, we prevent them from propagating
   into any arithmetic operations.
   2.

   *Logic Guard:* The check for samples_per_block <= 0 is critical because
   even if channels is positive, a small block_size relative to the channel
   count could result in a zero or negative value, which would still trigger
   the FPE in the vpk->block_count calculation.
   3.

   *FFmpeg Compliance:* Returning AVERROR_INVALIDDATA is the standard way
   to handle malformed files in the FFmpeg ecosystem, ensuring the application
   handles the error gracefully rather than crashing.


On Sat, Mar 28, 2026 at 11:27 AM Samyak Annapureddy <
[email protected]> wrote:

> *Hello FFmpeg Developers,*
>
> I am reporting a Floating Point Exception (FPE) in the VPK demuxer (
> libavformat/vpk.c) discovered via fuzzing. The crash occurs when
> processing a crafted 21-byte VPK file, likely due to an unvalidated header
> value causing a division by zero.
>
> *Reproduction:*
>
>    1.
>
>    Build FFmpeg from the latest master (as of late March 2026).
>    2.
>
>    Run the following command: ffmpeg -i [attached_crash_file] -f null -
>
> *Observed Result:* The process terminates with a Floating point
> exception: 8 (or UndefinedBehaviorSanitizer: division by zero).
>
> *Expected Result:* The demuxer should validate the header and return
> AVERROR_INVALIDDATA instead of crashing.
>
> *Hello FFmpeg Developers,*
>
> I have discovered a Floating Point Exception (division by zero) in the VPK
> demuxer (libavformat/vpk.c) using a fuzzer. The crash is triggered by the
> attached 21-byte PoC file.
>
> *Reproduction:* ffmpeg -i vpk_crash_poc -f null -
>
> *Tested on:*
>
>    -
>
>    *OS:* macOS (Apple Silicon)
>    -
>
>    *Git Hash:* f76aa4e4087569f99af1b4d87c04f160fb2378ce
>    -
>
>    *Result:* Floating point exception: 8 (or UndefinedBehaviorSanitizer:
>    division by zero)
>
> *Analysis:* The crash appears to occur during header parsing where a
> sample rate or channel count of zero is not properly validated before being
> used in a division operation.
>
> Please see the attached 21-byte PoC file.
>
> *Best regards,* Samyak
>
>
> CRASH FILE :
>
>
>
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to