UBSan: signed left shift 1<<31 when testing APE header flag in ReadMP3APETag...
Analyzes and adjusts the volume of MP3 files
Brought to you by:
snelg
UBSan reports undefined behavior in ReadMP3APETag() when checking the APEv2 footer Flags field.
File: apetag.c
Line: 319
if ( Read_LE_Uint32 (T.Flags) & (1<<31) ) {
// Tag contains header
}
The expression 1 << 31 performs a left shift on a signed integer.
In C, the integer constant 1 has type int. Shifting it by 31 bits produces a value that cannot be represented by a signed integer, resulting in undefined behavior.
apetag.c:319:39: runtime error:
left shift of 1 by 31 places cannot be represented in type 'int'
ReadMP3APETag()
ReadMP3GainAPETag()
main()
Build mp3gain with UndefinedBehaviorSanitizer enabled and run:
mp3gain poc_apetag_319_ReadMP3APETag.mp3
The program should check the APE header flag without triggering undefined behavior.
UBSan aborts at apetag.c:319.
Replace:
1 << 31
with:
1U << 31
or:
(uint32_t)1 << 31
A crashing test case is attached.
Reproduction
Build mp3gain with UndefinedBehaviorSanitizer enabled.
Run:
export UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_stacktrace=1
./mp3gain poc_apetag_319_ReadMP3APETag.mp3
The attached PoC triggers the UBSan report.