Loading media/libaudioclient/AudioTrackShared.cpp +8 −25 Original line number Diff line number Diff line Loading @@ -20,30 +20,13 @@ #include <android-base/macros.h> #include <private/media/AudioTrackShared.h> #include <utils/Log.h> #include <audio_utils/safe_math.h> #include <linux/futex.h> #include <sys/syscall.h> namespace android { // TODO: consider pulling this into a shared header. // safe_sub_overflow is used ensure that subtraction occurs in the same native type // with proper 2's complement overflow. Without calling this function, it is possible, // for example, that optimizing compilers may elect to treat 32 bit subtraction // as 64 bit subtraction when storing into a 64 bit destination as integer overflow is // technically undefined. template<typename T, typename U, typename = std::enable_if_t<std::is_same<std::decay_t<T>, std::decay_t<U>>{}>> // ensure arguments are same type (ignoring volatile, which is used in cblk variables). auto safe_sub_overflow(const T& a, const U& b) { std::decay_t<T> result; (void)__builtin_sub_overflow(a, b, &result); // note if __builtin_sub_overflow returns true, an overflow occurred. return result; } // used to clamp a value to size_t. TODO: move to another file. template <typename T> size_t clampToSize(T x) { Loading Loading @@ -204,7 +187,7 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques front = cblk->u.mStreaming.mFront; } // write to rear, read from front ssize_t filled = safe_sub_overflow(rear, front); ssize_t filled = audio_utils::safe_sub_overflow(rear, front); // pipe should not be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { if (mIsOut) { Loading Loading @@ -702,7 +685,7 @@ void ServerProxy::flushBufferIfNeeded() const size_t overflowBit = mFrameCountP2 << 1; const size_t mask = overflowBit - 1; int32_t newFront = (front & ~mask) | (flush & mask); ssize_t filled = safe_sub_overflow(rear, newFront); ssize_t filled = audio_utils::safe_sub_overflow(rear, newFront); if (filled >= (ssize_t)overflowBit) { // front and rear offsets span the overflow bit of the p2 mask // so rebasing newFront on the front offset is off by the overflow bit. Loading Loading @@ -744,7 +727,7 @@ int32_t AudioTrackServerProxy::getRear() const const size_t overflowBit = mFrameCountP2 << 1; const size_t mask = overflowBit - 1; int32_t newRear = (rear & ~mask) | (stop & mask); ssize_t filled = safe_sub_overflow(newRear, front); ssize_t filled = audio_utils::safe_sub_overflow(newRear, front); // overflowBit is unsigned, so cast to signed for comparison. if (filled >= (ssize_t)overflowBit) { // front and rear offsets span the overflow bit of the p2 mask Loading Loading @@ -796,7 +779,7 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear; } ssize_t filled = safe_sub_overflow(rear, front); ssize_t filled = audio_utils::safe_sub_overflow(rear, front); // pipe should not already be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down", Loading Loading @@ -923,7 +906,7 @@ size_t AudioTrackServerProxy::framesReady() return mFrameCount; } const int32_t rear = getRear(); ssize_t filled = safe_sub_overflow(rear, cblk->u.mStreaming.mFront); ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront); // pipe should not already be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down", Loading @@ -949,7 +932,7 @@ size_t AudioTrackServerProxy::framesReadySafe() const return mFrameCount; } const int32_t rear = getRear(); const ssize_t filled = safe_sub_overflow(rear, cblk->u.mStreaming.mFront); const ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront); if (!(0 <= filled && (size_t) filled <= mFrameCount)) { return 0; // error condition, silently return 0. } Loading Loading @@ -1259,7 +1242,7 @@ size_t AudioRecordServerProxy::framesReadySafe() const } const int32_t front = android_atomic_acquire_load(&mCblk->u.mStreaming.mFront); const int32_t rear = mCblk->u.mStreaming.mRear; const ssize_t filled = safe_sub_overflow(rear, front); const ssize_t filled = audio_utils::safe_sub_overflow(rear, front); if (!(0 <= filled && (size_t) filled <= mFrameCount)) { return 0; // error condition, silently return 0. } Loading services/audioflinger/Threads.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include <audio_utils/primitives.h> #include <audio_utils/format.h> #include <audio_utils/minifloat.h> #include <audio_utils/safe_math.h> #include <system/audio_effects/effect_ns.h> #include <system/audio_effects/effect_aec.h> #include <system/audio.h> Loading Loading @@ -7904,7 +7905,7 @@ void AudioFlinger::RecordThread::ResamplerBufferProvider::sync( RecordThread *recordThread = (RecordThread *) threadBase.get(); const int32_t rear = recordThread->mRsmpInRear; const int32_t front = mRsmpInFront; const ssize_t filled = rear - front; const ssize_t filled = audio_utils::safe_sub_overflow(rear, front); size_t framesIn; bool overrun = false; Loading @@ -7918,7 +7919,8 @@ void AudioFlinger::RecordThread::ResamplerBufferProvider::sync( } else { // client is not keeping up with server, but give it latest data framesIn = recordThread->mRsmpInFrames; mRsmpInFront = /* front = */ rear - framesIn; mRsmpInFront = /* front = */ audio_utils::safe_sub_overflow( rear, static_cast<int32_t>(framesIn)); overrun = true; } if (framesAvailable != NULL) { Loading @@ -7942,7 +7944,7 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer( RecordThread *recordThread = (RecordThread *) threadBase.get(); int32_t rear = recordThread->mRsmpInRear; int32_t front = mRsmpInFront; ssize_t filled = rear - front; ssize_t filled = audio_utils::safe_sub_overflow(rear, front); // FIXME should not be P2 (don't want to increase latency) // FIXME if client not keeping up, discard LOG_ALWAYS_FATAL_IF(!(0 <= filled && (size_t) filled <= recordThread->mRsmpInFrames)); Loading Loading @@ -7975,13 +7977,13 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer( void AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer( AudioBufferProvider::Buffer* buffer) { size_t stepCount = buffer->frameCount; int32_t stepCount = static_cast<int32_t>(buffer->frameCount); if (stepCount == 0) { return; } ALOG_ASSERT(stepCount <= mRsmpInUnrel); mRsmpInUnrel -= stepCount; mRsmpInFront += stepCount; mRsmpInFront = audio_utils::safe_add_overflow(mRsmpInFront, stepCount); buffer->raw = NULL; buffer->frameCount = 0; } Loading Loading
media/libaudioclient/AudioTrackShared.cpp +8 −25 Original line number Diff line number Diff line Loading @@ -20,30 +20,13 @@ #include <android-base/macros.h> #include <private/media/AudioTrackShared.h> #include <utils/Log.h> #include <audio_utils/safe_math.h> #include <linux/futex.h> #include <sys/syscall.h> namespace android { // TODO: consider pulling this into a shared header. // safe_sub_overflow is used ensure that subtraction occurs in the same native type // with proper 2's complement overflow. Without calling this function, it is possible, // for example, that optimizing compilers may elect to treat 32 bit subtraction // as 64 bit subtraction when storing into a 64 bit destination as integer overflow is // technically undefined. template<typename T, typename U, typename = std::enable_if_t<std::is_same<std::decay_t<T>, std::decay_t<U>>{}>> // ensure arguments are same type (ignoring volatile, which is used in cblk variables). auto safe_sub_overflow(const T& a, const U& b) { std::decay_t<T> result; (void)__builtin_sub_overflow(a, b, &result); // note if __builtin_sub_overflow returns true, an overflow occurred. return result; } // used to clamp a value to size_t. TODO: move to another file. template <typename T> size_t clampToSize(T x) { Loading Loading @@ -204,7 +187,7 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques front = cblk->u.mStreaming.mFront; } // write to rear, read from front ssize_t filled = safe_sub_overflow(rear, front); ssize_t filled = audio_utils::safe_sub_overflow(rear, front); // pipe should not be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { if (mIsOut) { Loading Loading @@ -702,7 +685,7 @@ void ServerProxy::flushBufferIfNeeded() const size_t overflowBit = mFrameCountP2 << 1; const size_t mask = overflowBit - 1; int32_t newFront = (front & ~mask) | (flush & mask); ssize_t filled = safe_sub_overflow(rear, newFront); ssize_t filled = audio_utils::safe_sub_overflow(rear, newFront); if (filled >= (ssize_t)overflowBit) { // front and rear offsets span the overflow bit of the p2 mask // so rebasing newFront on the front offset is off by the overflow bit. Loading Loading @@ -744,7 +727,7 @@ int32_t AudioTrackServerProxy::getRear() const const size_t overflowBit = mFrameCountP2 << 1; const size_t mask = overflowBit - 1; int32_t newRear = (rear & ~mask) | (stop & mask); ssize_t filled = safe_sub_overflow(newRear, front); ssize_t filled = audio_utils::safe_sub_overflow(newRear, front); // overflowBit is unsigned, so cast to signed for comparison. if (filled >= (ssize_t)overflowBit) { // front and rear offsets span the overflow bit of the p2 mask Loading Loading @@ -796,7 +779,7 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear; } ssize_t filled = safe_sub_overflow(rear, front); ssize_t filled = audio_utils::safe_sub_overflow(rear, front); // pipe should not already be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down", Loading Loading @@ -923,7 +906,7 @@ size_t AudioTrackServerProxy::framesReady() return mFrameCount; } const int32_t rear = getRear(); ssize_t filled = safe_sub_overflow(rear, cblk->u.mStreaming.mFront); ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront); // pipe should not already be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down", Loading @@ -949,7 +932,7 @@ size_t AudioTrackServerProxy::framesReadySafe() const return mFrameCount; } const int32_t rear = getRear(); const ssize_t filled = safe_sub_overflow(rear, cblk->u.mStreaming.mFront); const ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront); if (!(0 <= filled && (size_t) filled <= mFrameCount)) { return 0; // error condition, silently return 0. } Loading Loading @@ -1259,7 +1242,7 @@ size_t AudioRecordServerProxy::framesReadySafe() const } const int32_t front = android_atomic_acquire_load(&mCblk->u.mStreaming.mFront); const int32_t rear = mCblk->u.mStreaming.mRear; const ssize_t filled = safe_sub_overflow(rear, front); const ssize_t filled = audio_utils::safe_sub_overflow(rear, front); if (!(0 <= filled && (size_t) filled <= mFrameCount)) { return 0; // error condition, silently return 0. } Loading
services/audioflinger/Threads.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include <audio_utils/primitives.h> #include <audio_utils/format.h> #include <audio_utils/minifloat.h> #include <audio_utils/safe_math.h> #include <system/audio_effects/effect_ns.h> #include <system/audio_effects/effect_aec.h> #include <system/audio.h> Loading Loading @@ -7904,7 +7905,7 @@ void AudioFlinger::RecordThread::ResamplerBufferProvider::sync( RecordThread *recordThread = (RecordThread *) threadBase.get(); const int32_t rear = recordThread->mRsmpInRear; const int32_t front = mRsmpInFront; const ssize_t filled = rear - front; const ssize_t filled = audio_utils::safe_sub_overflow(rear, front); size_t framesIn; bool overrun = false; Loading @@ -7918,7 +7919,8 @@ void AudioFlinger::RecordThread::ResamplerBufferProvider::sync( } else { // client is not keeping up with server, but give it latest data framesIn = recordThread->mRsmpInFrames; mRsmpInFront = /* front = */ rear - framesIn; mRsmpInFront = /* front = */ audio_utils::safe_sub_overflow( rear, static_cast<int32_t>(framesIn)); overrun = true; } if (framesAvailable != NULL) { Loading @@ -7942,7 +7944,7 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer( RecordThread *recordThread = (RecordThread *) threadBase.get(); int32_t rear = recordThread->mRsmpInRear; int32_t front = mRsmpInFront; ssize_t filled = rear - front; ssize_t filled = audio_utils::safe_sub_overflow(rear, front); // FIXME should not be P2 (don't want to increase latency) // FIXME if client not keeping up, discard LOG_ALWAYS_FATAL_IF(!(0 <= filled && (size_t) filled <= recordThread->mRsmpInFrames)); Loading Loading @@ -7975,13 +7977,13 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer( void AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer( AudioBufferProvider::Buffer* buffer) { size_t stepCount = buffer->frameCount; int32_t stepCount = static_cast<int32_t>(buffer->frameCount); if (stepCount == 0) { return; } ALOG_ASSERT(stepCount <= mRsmpInUnrel); mRsmpInUnrel -= stepCount; mRsmpInFront += stepCount; mRsmpInFront = audio_utils::safe_add_overflow(mRsmpInFront, stepCount); buffer->raw = NULL; buffer->frameCount = 0; } Loading