Menu

#66 UBSan: signed left shift 1<<31 when writing APE header flags in WriteMP3GainAPETag (apetag.c:531)

v1.0 (example)
open
nobody
3
2026-09-12
2026-09-12
mu mu
No

Description

UBSan reports undefined behavior in WriteMP3GainAPETag() when writing APEv2 header flags.

Environment

  • Version: mp3gain 1.6.2
  • OS: Ubuntu Linux
  • Compiler: clang
  • Sanitizer: UndefinedBehaviorSanitizer (UBSan)

Affected code

File: apetag.c

Line: 531

Write_LE_Uint32(newHeader.Flags,1<<31 | 1<<29); 
/* tag has header, this _is_ the header */

Problem

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.

UBSan report

apetag.c:531:36: runtime error:
left shift of 1 by 31 places cannot be represented in type 'int'

Stack trace

WriteMP3GainAPETag()
WriteMP3GainTag()
main()

Reproduction

Build mp3gain with UndefinedBehaviorSanitizer enabled.

Run:

export UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_stacktrace=1

./mp3gain poc_apetag_531_WriteMP3GainAPETag.mp3

The attached PoC triggers the UBSan report.

Expected result

Writing APEv2 header flags should not trigger undefined behavior.

Actual result

UBSan aborts at apetag.c:531 while constructing APE header flags.

Suggested fix

Replace:

1 << 31 | 1 << 29

with:

(1U << 31) | (1U << 29)

A crashing test case is attached.

1 Attachments

Discussion


Log in to post a comment.