Opened 4 years ago

Closed 4 years ago

#8487 closed defect (fixed)

UBSan: left shift of negative value

Reported by: andreafioraldi Owned by:
Priority: minor Component: avcodec
Version: git-master Keywords: adpcm ubsan
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description (last modified by Carl Eugen Hoyos)

Build ffmpeg 4.2.2 using clang and ubsan (-fsanitize=undefined).
Command line: ./ffmpeg.ubsan -y -i ./input -c:v mpeg4 -c:a out.mp4
Output:


ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
  built with clang version 8.0.0-3~ubuntu18.04.2 (tags/RELEASE_800/final)
  configuration: --cc=clang-8 --cxx=clang++-8 --ld=clang-8
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
Trailing options were found on the commandline.
[ea_cdata @ 0x902f600] Format ea_cdata detected only with low score of 12, misdetection possible!
Ignoring attempt to set invalid timebase 1/0 for st:0
libavcodec/adpcm.c:1415:50: runtime error: left shift of negative value -2
libavcodec/adpcm.c:1411:55: runtime error: left shift of negative value -1
[ea_cdata @ 0x902f600] decoding for stream 0 failed
[ea_cdata @ 0x902f600] Could not find codec parameters for stream 0 (Audio: adpcm_ea_xas, 1 channels, s16p): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Guessed Channel Layout for Input Stream #0.0 : mono
Input #0, ea_cdata, from './ffmpeg_ubsan_out/f1/crashes/id:000013,sig:04,src:001011+001703,time:2202546,op:splice,rep:16':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Audio: adpcm_ea_xas, mono, s16p
At least one output file must be specified

Look at:

    case AV_CODEC_ID_ADPCM_EA_XAS:
        for (channel=0; channel<avctx->channels; channel++) {
                ...
                val = sign_extend(bytestream2_get_le16u(&gb), 16);
                shift[n] = 20 - (val & 0x0F);
                ...
            }

            for (m=2; m<32; m+=2) {
                ...
                for (n = 0; n < 4; n++, s += 32) {
                    ..
                    level = sign_extend(byte >> 4, 4) << shift[n]; //line 1415
                    ...
                }
            }
        }

This bug really does not make sense to me, val is controlled but the 0x0f mask should prevent to have a negative shift[n] value.
UBSan has no false positives, so there is a bug indeed, but I don't understand why.
Maybe there is something really bad with n indexes or some shady clang optimization that assumed bad things.

I attach a file to reproduce the issue in base64:

BAAAAABQX0UvBf//Bf93/3wIAAAAKAAAABBFMDAAABAATjs0MP93/1NBVUNFKTBtTncIAAAAE15BVV9FLzAMRm7/d/93B+4AACgAAABiRTAlOzQwbU47NCBtTgA=

Attachments (1)

input (92 bytes ) - added by Carl Eugen Hoyos 4 years ago.

Download all attachments as: .zip

Change History (4)

comment:1 by andreafioraldi, 4 years ago

Okok sorry, sleepless saturday night, it is obviously sign_extend(byte >> 4, 4) that is negative, not shift[n].

comment:2 by Carl Eugen Hoyos, 4 years ago

Description: modified (diff)
Keywords: adpcm added
Priority: normalminor
Reproduced by developer: set
Status: newopen
Version: 4.2git-master

by Carl Eugen Hoyos, 4 years ago

Attachment: input added

comment:3 by Carl Eugen Hoyos, 4 years ago

Resolution: fixed
Status: openclosed

Fixed by Andreas Rheinhardt in 3ad8af51b7c0a968ac3fd62964780d4ff9136c5a

Note: See TracTickets for help on using tickets.