Track: Check buffer size
Test: Native POC
Bug: 38340117
Change-Id: Ia7edd9a802905214a27961dbcec6352f6ef98f73
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index d7c0728..27c6d35 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -474,6 +474,7 @@
format,
frameCount,
NULL,
+ (size_t)0 /* bufferSize */,
AUDIO_INPUT_FLAG_NONE);
if (patch->mPatchRecord == 0) {
return NO_MEMORY;
@@ -494,6 +495,7 @@
format,
frameCount,
patch->mPatchRecord->buffer(),
+ patch->mPatchRecord->bufferSize(),
AUDIO_OUTPUT_FLAG_NONE);
if (patch->mPatchTrack == 0) {
return NO_MEMORY;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 3f1a0c0..af644ed 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -30,6 +30,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
const sp<IMemory>& sharedBuffer,
audio_session_t sessionId,
uid_t uid,
@@ -240,6 +241,7 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_output_flags_t flags);
virtual ~PatchTrack();
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 3f83ca8..071a329 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -29,6 +29,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t uid,
audio_input_flags_t flags,
@@ -102,6 +103,7 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_input_flags_t flags);
virtual ~PatchRecord();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index df10d23..b2d0a72 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2018,7 +2018,8 @@
}
track = new Track(this, client, streamType, sampleRate, format,
- channelMask, frameCount, NULL, sharedBuffer,
+ channelMask, frameCount,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
@@ -6700,7 +6701,8 @@
Mutex::Autolock _l(mLock);
track = new RecordTrack(this, client, sampleRate,
- format, channelMask, frameCount, NULL, sessionId, uid,
+ format, channelMask, frameCount,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid,
*flags, TrackBase::TYPE_DEFAULT, portId);
lStatus = track->initCheck();
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index cb540ca..9c27be8 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -61,6 +61,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t uid,
bool isOut,
@@ -82,6 +83,7 @@
sp<IMemory> getBuffers() const { return mBufferMemory; }
void* buffer() const { return mBuffer; }
+ size_t bufferSize() const { return mBufferSize; }
virtual bool isFastTrack() const = 0;
bool isOutputTrack() const { return (mType == TYPE_OUTPUT); }
bool isPatchTrack() const { return (mType == TYPE_PATCH); }
@@ -144,6 +146,7 @@
sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only
void* mBuffer; // start of track buffer, typically in shared memory
// except for OutputTrack when it is in local memory
+ size_t mBufferSize; // size of mBuffer in bytes
// we don't really need a lock for these
track_state mState;
const uint32_t mSampleRate; // initial sample rate only; for tracks which
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 9cab4c7..37c5764 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -71,6 +71,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t clientUid,
bool isOut,
@@ -81,7 +82,7 @@
mThread(thread),
mClient(client),
mCblk(NULL),
- // mBuffer
+ // mBuffer, mBufferSize
mState(IDLE),
mSampleRate(sampleRate),
mFormat(format),
@@ -113,15 +114,22 @@
// ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
- size_t bufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
+ size_t minBufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
// check overflow when computing bufferSize due to multiplication by mFrameSize.
- if (bufferSize < frameCount // roundup rounds down for values above UINT_MAX / 2
+ if (minBufferSize < frameCount // roundup rounds down for values above UINT_MAX / 2
|| mFrameSize == 0 // format needs to be correct
- || bufferSize > SIZE_MAX / mFrameSize) {
+ || minBufferSize > SIZE_MAX / mFrameSize) {
android_errorWriteLog(0x534e4554, "34749571");
return;
}
- bufferSize *= mFrameSize;
+ minBufferSize *= mFrameSize;
+
+ if (buffer == nullptr) {
+ bufferSize = minBufferSize; // allocated here.
+ } else if (minBufferSize > bufferSize) {
+ android_errorWriteLog(0x534e4554, "38340117");
+ return;
+ }
size_t size = sizeof(audio_track_cblk_t);
if (buffer == NULL && alloc == ALLOC_CBLK) {
@@ -177,6 +185,7 @@
// It should references the buffer via the pipe.
// Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
mBuffer = NULL;
+ bufferSize = 0;
break;
case ALLOC_CBLK:
// clear all buffers
@@ -196,7 +205,10 @@
case ALLOC_NONE:
mBuffer = buffer;
break;
+ default:
+ LOG_ALWAYS_FATAL("invalid allocation type: %d", (int)alloc);
}
+ mBufferSize = bufferSize;
#ifdef TEE_SINK
if (mTeeSinkTrackEnabled) {
@@ -368,6 +380,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
const sp<IMemory>& sharedBuffer,
audio_session_t sessionId,
uid_t uid,
@@ -376,6 +389,7 @@
audio_port_handle_t portId)
: TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
(sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
+ (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
sessionId, uid, true /*isOut*/,
(type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
type, portId),
@@ -1220,7 +1234,8 @@
uid_t uid)
: Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
sampleRate, format, channelMask, frameCount,
- NULL, 0, AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
+ AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
TYPE_OUTPUT),
mActive(false), mSourceThread(sourceThread)
{
@@ -1417,10 +1432,12 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_output_flags_t flags)
: Track(playbackThread, NULL, streamType,
sampleRate, format, channelMask, frameCount,
- buffer, 0, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
+ buffer, bufferSize, nullptr /* sharedBuffer */,
+ AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
{
uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
@@ -1554,13 +1571,14 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t uid,
audio_input_flags_t flags,
track_type type,
audio_port_handle_t portId)
: TrackBase(thread, client, sampleRate, format,
- channelMask, frameCount, buffer, sessionId, uid, false /*isOut*/,
+ channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
(type == TYPE_DEFAULT) ?
((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
@@ -1754,9 +1772,10 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_input_flags_t flags)
: RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
- buffer, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
+ buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
{
uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
@@ -1823,7 +1842,9 @@
uid_t uid,
audio_port_handle_t portId)
: TrackBase(thread, NULL, sampleRate, format,
- channelMask, 0, NULL, sessionId, uid, false,
+ channelMask, (size_t)0 /* frameCount */,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */,
+ sessionId, uid, false /* isOut */,
ALLOC_NONE,
TYPE_DEFAULT, portId)
{