Changeset 272678 in webkit
- Timestamp:
- Feb 10, 2021 12:34:18 PM (3 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r272665 r272678 1 2021-02-10 Chris Dumez <cdumez@apple.com> 2 3 WebCore::createBusFromInMemoryAudioFile() may crash under ExtAudioFileRead() 4 https://bugs.webkit.org/show_bug.cgi?id=221642 5 <rdar://72789841> 6 7 Reviewed by Geoffrey Garen. 8 9 The crash seems to indicate we are passing an AudioBufferList to ExtAudioFileRead() 10 that contains a null buffer. It is not obvious how this is happening but I have made 11 the following changes: 12 1. createAudioBufferList() / destroyAudioListBuffer() implementation is now shared 13 on both macOS and iOS. The implementation now uses fastCalloc and returns null 14 in case of failure to allocate. 15 2. createAudioBufferList() was renamed to tryCreateAudioBufferList() to make it clear 16 it can return null. All call sites now properly deal with tryCreateAudioBufferList() 17 potentially return null 18 3. Add a new validateAudioBufferList() function which makes sure that the AudioBufferList 19 we are about to pass to ExtAudioFileRead() does not contain any null buffer. In case 20 of validation failure, we log an error, generate a simulated crash log and early return 21 gracefully instead of crashing later on. 22 4. Added more assertions to help catch bugs. 23 24 * SourcesCocoa.txt: 25 * WebCore.xcodeproj/project.pbxproj: 26 * platform/audio/cocoa/AudioFileReaderCocoa.cpp: Added. 27 (WebCore::tryCreateAudioBufferList): 28 (WebCore::destroyAudioBufferList): 29 (WebCore::validateAudioBufferList): 30 * platform/audio/cocoa/AudioFileReaderCocoa.h: Added. 31 * platform/audio/ios/AudioFileReaderIOS.cpp: 32 (WebCore::AudioFileReader::createBus): 33 (WebCore::createAudioBufferList): Deleted. 34 (WebCore::destroyAudioBufferList): Deleted. 35 * platform/audio/mac/AudioFileReaderMac.cpp: 36 (WebCore::AudioFileReader::createBus): 37 (WebCore::createAudioBufferList): Deleted. 38 (WebCore::destroyAudioBufferList): Deleted. 39 1 40 2021-02-10 Aditya Keerthi <akeerthi@apple.com> 2 41 -
trunk/Source/WebCore/SourcesCocoa.txt
r272603 r272678 206 206 platform/audio/AudioSession.cpp 207 207 platform/audio/cocoa/AudioDestinationCocoa.cpp 208 platform/audio/cocoa/AudioFileReaderCocoa.cpp 208 209 platform/audio/cocoa/AudioOutputUnitAdaptor.cpp 209 210 platform/audio/cocoa/AudioSampleBufferList.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r272630 r272678 1262 1262 4682D2001F79783000C863DB /* StoredCredentialsPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 4682D1FF1F79782300C863DB /* StoredCredentialsPolicy.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1263 1263 468344E01EDDFAAA00B7795B /* DOMRectList.h in Headers */ = {isa = PBXBuildFile; fileRef = 468344DE1EDDFA5F00B7795B /* DOMRectList.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1264 46AAAA3D25D3632000BAF42F /* AudioFileReaderCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 46AAAA3A25D3631400BAF42F /* AudioFileReaderCocoa.h */; }; 1264 1265 46B63F6C1C6E8D19002E914B /* JSEventTargetCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B63F6B1C6E8CDF002E914B /* JSEventTargetCustom.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1265 1266 46B650DD2296262700FD8AA4 /* PageIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B650DB2296262700FD8AA4 /* PageIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 8197 8198 468344DE1EDDFA5F00B7795B /* DOMRectList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DOMRectList.h; sourceTree = "<group>"; }; 8198 8199 468B8BDE25CC849300F67822 /* JSBaseAudioContextCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSBaseAudioContextCustom.cpp; sourceTree = "<group>"; }; 8200 46AAAA3A25D3631400BAF42F /* AudioFileReaderCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioFileReaderCocoa.h; sourceTree = "<group>"; }; 8201 46AAAA3C25D3631400BAF42F /* AudioFileReaderCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioFileReaderCocoa.cpp; sourceTree = "<group>"; }; 8199 8202 46B63F6B1C6E8CDF002E914B /* JSEventTargetCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEventTargetCustom.h; sourceTree = "<group>"; }; 8200 8203 46B650DB2296262700FD8AA4 /* PageIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageIdentifier.h; sourceTree = "<group>"; }; … … 27939 27942 413151842357745E00115E6E /* AudioDestinationCocoa.cpp */, 27940 27943 413151862357745E00115E6E /* AudioDestinationCocoa.h */, 27944 46AAAA3C25D3631400BAF42F /* AudioFileReaderCocoa.cpp */, 27945 46AAAA3A25D3631400BAF42F /* AudioFileReaderCocoa.h */, 27941 27946 1DB66D38253678EA00B671B9 /* AudioOutputUnitAdaptor.cpp */, 27942 27947 1DB66D37253678EA00B671B9 /* AudioOutputUnitAdaptor.h */, … … 31237 31242 FD31608212B026F700C1A359 /* AudioDSPKernelProcessor.h in Headers */, 31238 31243 FD31608312B026F700C1A359 /* AudioFileReader.h in Headers */, 31244 46AAAA3D25D3632000BAF42F /* AudioFileReaderCocoa.h in Headers */, 31239 31245 CD5596921475B678001D0BD0 /* AudioFileReaderIOS.h in Headers */, 31240 31246 FD3160BF12B0272A00C1A359 /* AudioFileReaderMac.h in Headers */, -
trunk/Source/WebCore/platform/audio/ios/AudioFileReaderIOS.cpp
r268414 r272678 35 35 #include "AudioBus.h" 36 36 #include "AudioFileReader.h" 37 #include "AudioFileReaderCocoa.h" 38 #include "Logging.h" 37 39 #include <CoreFoundation/CoreFoundation.h> 38 40 #include <wtf/CheckedArithmetic.h> … … 52 54 namespace WebCore { 53 55 54 static WARN_UNUSED_RETURN AudioBufferList* createAudioBufferList(size_t numberOfBuffers)55 {56 CheckedSize bufferListSize = sizeof(AudioBufferList) - sizeof(AudioBuffer);57 bufferListSize += numberOfBuffers * sizeof(AudioBuffer);58 59 AudioBufferList* bufferList = static_cast<AudioBufferList*>(calloc(1, bufferListSize.unsafeGet()));60 if (bufferList)61 bufferList->mNumberBuffers = numberOfBuffers;62 return bufferList;63 }64 65 static inline void destroyAudioBufferList(AudioBufferList* bufferList)66 {67 free(bufferList);68 }69 70 56 AudioFileReader::AudioFileReader(const char* filePath) 71 57 : m_data(0) … … 185 171 AudioFloatArray rightChannel; 186 172 187 AudioBufferList* bufferList = createAudioBufferList(numberOfChannels); 188 if (!bufferList) 189 return nullptr; 173 AudioBufferList* bufferList = tryCreateAudioBufferList(numberOfChannels); 174 if (!bufferList) { 175 RELEASE_LOG_FAULT(WebAudio, "tryCreateAudioBufferList(%ld) returned null", numberOfChannels); 176 return nullptr; 177 } 190 178 const size_t bufferSize = numberOfFrames * sizeof(float); 191 179 180 RELEASE_ASSERT(bufferList->mNumberBuffers == numberOfChannels); 192 181 if (mixToMono && numberOfChannels == 2) { 193 182 leftChannel.resize(numberOfFrames); … … 202 191 bufferList->mBuffers[1].mData = rightChannel.data(); 203 192 } else { 204 ASSERT(!mixToMono || numberOfChannels == 1);193 RELEASE_ASSERT(!mixToMono || numberOfChannels == 1); 205 194 206 195 // For True-stereo (numberOfChannels == 4) … … 210 199 bufferList->mBuffers[i].mDataByteSize = bufferSize; 211 200 bufferList->mBuffers[i].mData = audioBus->channel(i)->mutableData(); 201 ASSERT(bufferList->mBuffers[i].mData); 212 202 } 203 } 204 205 if (!validateAudioBufferList(bufferList)) { 206 RELEASE_LOG_FAULT(WebAudio, "Generated buffer in AudioFileReader::createBus() did not pass validation"); 207 ASSERT_NOT_REACHED(); 208 destroyAudioBufferList(bufferList); 209 return nullptr; 213 210 } 214 211 -
trunk/Source/WebCore/platform/audio/mac/AudioFileReaderMac.cpp
r268414 r272678 37 37 #include "AudioBus.h" 38 38 #include "AudioFileReader.h" 39 #include "AudioFileReaderCocoa.h" 39 40 #include "FloatConversion.h" 41 #include "Logging.h" 40 42 #include <CoreFoundation/CoreFoundation.h> 41 43 #include <wtf/RetainPtr.h> 42 44 43 45 namespace WebCore { 44 45 static AudioBufferList* createAudioBufferList(size_t numberOfBuffers)46 {47 size_t bufferListSize = sizeof(AudioBufferList) - sizeof(AudioBuffer);48 bufferListSize += numberOfBuffers * sizeof(AudioBuffer);49 50 AudioBufferList* bufferList = static_cast<AudioBufferList*>(calloc(1, bufferListSize));51 if (bufferList)52 bufferList->mNumberBuffers = numberOfBuffers;53 54 return bufferList;55 }56 57 static void destroyAudioBufferList(AudioBufferList* bufferList)58 {59 free(bufferList);60 }61 46 62 47 AudioFileReader::AudioFileReader(const char* filePath) … … 191 176 192 177 // Setup AudioBufferList in preparation for reading 193 AudioBufferList* bufferList = createAudioBufferList(numberOfChannels); 194 178 AudioBufferList* bufferList = tryCreateAudioBufferList(numberOfChannels); 179 if (!bufferList) { 180 RELEASE_LOG_FAULT(WebAudio, "tryCreateAudioBufferList(%ld) returned null", numberOfChannels); 181 return nullptr; 182 } 183 184 RELEASE_ASSERT(bufferList->mNumberBuffers == numberOfChannels); 195 185 if (mixToMono && numberOfChannels == 2) { 196 186 bufL.resize(numberOfFrames); … … 207 197 bufferList->mBuffers[1].mData = bufferR; 208 198 } else { 209 ASSERT(!mixToMono || numberOfChannels == 1);199 RELEASE_ASSERT(!mixToMono || numberOfChannels == 1); 210 200 211 201 // for True-stereo (numberOfChannels == 4) … … 214 204 bufferList->mBuffers[i].mDataByteSize = numberOfFrames * sizeof(float); 215 205 bufferList->mBuffers[i].mData = audioBus->channel(i)->mutableData(); 206 ASSERT(bufferList->mBuffers[i].mData); 216 207 } 208 } 209 210 if (!validateAudioBufferList(bufferList)) { 211 RELEASE_LOG_FAULT(WebAudio, "Generated buffer in AudioFileReader::createBus() did not pass validation"); 212 ASSERT_NOT_REACHED(); 213 destroyAudioBufferList(bufferList); 214 return nullptr; 217 215 } 218 216
Note: See TracChangeset
for help on using the changeset viewer.