Merge "Improve visibility of IMemory security risks"

gugelfrei
Ytai Ben-tsvi 5 years ago committed by Android (Google) Code Review
commit 51eb2f447a

@ -989,7 +989,7 @@ int main(int argc, char **argv) {
failed = false; failed = false;
printf("getFrameAtTime(%s) => OK\n", filename); printf("getFrameAtTime(%s) => OK\n", filename);
VideoFrame *frame = (VideoFrame *)mem->pointer(); VideoFrame *frame = (VideoFrame *)mem->unsecurePointer();
CHECK_EQ(writeJpegFile("/sdcard/out.jpg", CHECK_EQ(writeJpegFile("/sdcard/out.jpg",
frame->getFlattenedData(), frame->getFlattenedData(),

@ -116,7 +116,7 @@ void MyStreamSource::onBufferAvailable(size_t index) {
sp<IMemory> mem = mBuffers.itemAt(index); sp<IMemory> mem = mBuffers.itemAt(index);
ssize_t n = read(mFd, mem->pointer(), mem->size()); ssize_t n = read(mFd, mem->unsecurePointer(), mem->size());
if (n <= 0) { if (n <= 0) {
mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
} else { } else {
@ -238,7 +238,7 @@ ssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) {
copy = mem->size() - mCurrentBufferOffset; copy = mem->size() - mCurrentBufferOffset;
} }
memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy); memcpy((uint8_t *)mem->unsecurePointer() + mCurrentBufferOffset, data, copy);
mCurrentBufferOffset += copy; mCurrentBufferOffset += copy;
if (mCurrentBufferOffset == mem->size()) { if (mCurrentBufferOffset == mem->size()) {

@ -321,7 +321,11 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::
} }
// memory must be within the address space of the heap // memory must be within the address space of the heap
if (memory->pointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset() || // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
if (memory->unsecurePointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset() ||
heap->getSize() < memory->offset() + memory->size() || heap->getSize() < memory->offset() + memory->size() ||
SIZE_MAX - memory->offset() < memory->size()) { SIZE_MAX - memory->offset() < memory->size()) {
android_errorWriteLog(0x534e4554, "76221123"); android_errorWriteLog(0x534e4554, "76221123");

@ -764,7 +764,11 @@ EncryptedLinearBlockBuffer::EncryptedLinearBlockBuffer(
const std::shared_ptr<C2LinearBlock> &block, const std::shared_ptr<C2LinearBlock> &block,
const sp<IMemory> &memory, const sp<IMemory> &memory,
int32_t heapSeqNum) int32_t heapSeqNum)
: Codec2Buffer(format, new ABuffer(memory->pointer(), memory->size())), // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
: Codec2Buffer(format, new ABuffer(memory->unsecurePointer(), memory->size())),
mBlock(block), mBlock(block),
mMemory(memory), mMemory(memory),
mHeapSeqNum(heapSeqNum) { mHeapSeqNum(heapSeqNum) {
@ -800,7 +804,7 @@ bool EncryptedLinearBlockBuffer::copyDecryptedContent(
if (view.size() < length) { if (view.size() < length) {
return false; return false;
} }
memcpy(view.data(), decrypted->pointer(), length); memcpy(view.data(), decrypted->unsecurePointer(), length);
return true; return true;
} }

@ -159,7 +159,11 @@ status_t AudioEffect::set(const effect_uuid_t *type,
mIEffect = iEffect; mIEffect = iEffect;
mCblkMemory = cblk; mCblkMemory = cblk;
mCblk = static_cast<effect_param_cblk_t*>(cblk->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
mCblk = static_cast<effect_param_cblk_t*>(cblk->unsecurePointer());
int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int); int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
mCblk->buffer = (uint8_t *)mCblk + bufOffset; mCblk->buffer = (uint8_t *)mCblk + bufOffset;

@ -759,7 +759,11 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
status = NO_INIT; status = NO_INIT;
goto exit; goto exit;
} }
iMemPointer = output.cblk ->pointer(); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
iMemPointer = output.cblk ->unsecurePointer();
if (iMemPointer == NULL) { if (iMemPointer == NULL) {
ALOGE("%s(%d): Could not get control block pointer", __func__, mPortId); ALOGE("%s(%d): Could not get control block pointer", __func__, mPortId);
status = NO_INIT; status = NO_INIT;
@ -774,7 +778,11 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
if (output.buffers == 0) { if (output.buffers == 0) {
buffers = cblk + 1; buffers = cblk + 1;
} else { } else {
buffers = output.buffers->pointer(); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
buffers = output.buffers->unsecurePointer();
if (buffers == NULL) { if (buffers == NULL) {
ALOGE("%s(%d): Could not get buffer pointer", __func__, mPortId); ALOGE("%s(%d): Could not get buffer pointer", __func__, mPortId);
status = NO_INIT; status = NO_INIT;

@ -406,7 +406,7 @@ status_t AudioTrack::set(
mDoNotReconnect = doNotReconnect; mDoNotReconnect = doNotReconnect;
ALOGV_IF(sharedBuffer != 0, "%s(): sharedBuffer: %p, size: %zu", ALOGV_IF(sharedBuffer != 0, "%s(): sharedBuffer: %p, size: %zu",
__func__, sharedBuffer->pointer(), sharedBuffer->size()); __func__, sharedBuffer->unsecurePointer(), sharedBuffer->size());
ALOGV("%s(): streamType %d frameCount %zu flags %04x", ALOGV("%s(): streamType %d frameCount %zu flags %04x",
__func__, streamType, frameCount, flags); __func__, streamType, frameCount, flags);
@ -1508,7 +1508,11 @@ status_t AudioTrack::createTrack_l()
status = NO_INIT; status = NO_INIT;
goto exit; goto exit;
} }
void *iMemPointer = iMem->pointer(); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
void *iMemPointer = iMem->unsecurePointer();
if (iMemPointer == NULL) { if (iMemPointer == NULL) {
ALOGE("%s(%d): Could not get control block pointer", __func__, mPortId); ALOGE("%s(%d): Could not get control block pointer", __func__, mPortId);
status = NO_INIT; status = NO_INIT;
@ -1563,7 +1567,11 @@ status_t AudioTrack::createTrack_l()
if (mSharedBuffer == 0) { if (mSharedBuffer == 0) {
buffers = cblk + 1; buffers = cblk + 1;
} else { } else {
buffers = mSharedBuffer->pointer(); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
buffers = mSharedBuffer->unsecurePointer();
if (buffers == NULL) { if (buffers == NULL) {
ALOGE("%s(%d): Could not get buffer pointer", __func__, mPortId); ALOGE("%s(%d): Could not get buffer pointer", __func__, mPortId);
status = NO_INIT; status = NO_INIT;

@ -62,7 +62,7 @@ public:
status_t status = remote()->transact(GET_CBLK, data, &reply); status_t status = remote()->transact(GET_CBLK, data, &reply);
if (status == NO_ERROR) { if (status == NO_ERROR) {
cblk = interface_cast<IMemory>(reply.readStrongBinder()); cblk = interface_cast<IMemory>(reply.readStrongBinder());
if (cblk != 0 && cblk->pointer() == NULL) { if (cblk != 0 && cblk->unsecurePointer() == NULL) {
cblk.clear(); cblk.clear();
} }
} }

@ -122,7 +122,7 @@ public:
status_t status = remote()->transact(GET_CBLK, data, &reply); status_t status = remote()->transact(GET_CBLK, data, &reply);
if (status == NO_ERROR) { if (status == NO_ERROR) {
cblk = interface_cast<IMemory>(reply.readStrongBinder()); cblk = interface_cast<IMemory>(reply.readStrongBinder());
if (cblk != 0 && cblk->pointer() == NULL) { if (cblk != 0 && cblk->unsecurePointer() == NULL) {
cblk.clear(); cblk.clear();
} }
} }

@ -70,8 +70,12 @@ public:
return DEAD_OBJECT; return DEAD_OBJECT;
} }
if (parcel->readInt32() != 0) { if (parcel->readInt32() != 0) {
// TODO: Using unsecurePointer() has some associated security
// pitfalls (see declaration for details).
// Either document why it is safe in this case or address
// the issue (e.g. by copying).
sharedBuffer = interface_cast<IMemory>(parcel->readStrongBinder()); sharedBuffer = interface_cast<IMemory>(parcel->readStrongBinder());
if (sharedBuffer == 0 || sharedBuffer->pointer() == NULL) { if (sharedBuffer == 0 || sharedBuffer->unsecurePointer() == NULL) {
return BAD_VALUE; return BAD_VALUE;
} }
} }
@ -269,13 +273,21 @@ public:
(void)parcel->read(&inputId, sizeof(audio_io_handle_t)); (void)parcel->read(&inputId, sizeof(audio_io_handle_t));
if (parcel->readInt32() != 0) { if (parcel->readInt32() != 0) {
cblk = interface_cast<IMemory>(parcel->readStrongBinder()); cblk = interface_cast<IMemory>(parcel->readStrongBinder());
if (cblk == 0 || cblk->pointer() == NULL) { // TODO: Using unsecurePointer() has some associated security
// pitfalls (see declaration for details).
// Either document why it is safe in this case or address
// the issue (e.g. by copying).
if (cblk == 0 || cblk->unsecurePointer() == NULL) {
return BAD_VALUE; return BAD_VALUE;
} }
} }
if (parcel->readInt32() != 0) { if (parcel->readInt32() != 0) {
buffers = interface_cast<IMemory>(parcel->readStrongBinder()); buffers = interface_cast<IMemory>(parcel->readStrongBinder());
if (buffers == 0 || buffers->pointer() == NULL) { // TODO: Using unsecurePointer() has some associated security
// pitfalls (see declaration for details).
// Either document why it is safe in this case or address
// the issue (e.g. by copying).
if (buffers == 0 || buffers->unsecurePointer() == NULL) {
return BAD_VALUE; return BAD_VALUE;
} }
} }

@ -173,7 +173,7 @@ ssize_t HeifDataSource::readAt(off64_t offset, size_t size) {
// copy from cache if the request falls entirely in cache // copy from cache if the request falls entirely in cache
if (offset + size <= mCachedOffset + mCachedSize) { if (offset + size <= mCachedOffset + mCachedSize) {
memcpy(mMemory->pointer(), mCache.get() + offset - mCachedOffset, size); memcpy(mMemory->unsecurePointer(), mCache.get() + offset - mCachedOffset, size);
return size; return size;
} }
@ -271,7 +271,7 @@ ssize_t HeifDataSource::readAt(off64_t offset, size_t size) {
if (bytesAvailable < (int64_t)size) { if (bytesAvailable < (int64_t)size) {
size = bytesAvailable; size = bytesAvailable;
} }
memcpy(mMemory->pointer(), mCache.get() + offset - mCachedOffset, size); memcpy(mMemory->unsecurePointer(), mCache.get() + offset - mCachedOffset, size);
return size; return size;
} }
@ -360,12 +360,16 @@ bool HeifDecoderImpl::init(HeifStream* stream, HeifFrameInfo* frameInfo) {
sp<IMemory> sharedMem = mRetriever->getImageAtIndex( sp<IMemory> sharedMem = mRetriever->getImageAtIndex(
-1, mOutputColor, true /*metaOnly*/); -1, mOutputColor, true /*metaOnly*/);
if (sharedMem == nullptr || sharedMem->pointer() == nullptr) { if (sharedMem == nullptr || sharedMem->unsecurePointer() == nullptr) {
ALOGE("init: videoFrame is a nullptr"); ALOGE("init: videoFrame is a nullptr");
return false; return false;
} }
VideoFrame* videoFrame = static_cast<VideoFrame*>(sharedMem->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoFrame* videoFrame = static_cast<VideoFrame*>(sharedMem->unsecurePointer());
ALOGV("Image dimension %dx%d, display %dx%d, angle %d, iccSize %d", ALOGV("Image dimension %dx%d, display %dx%d, angle %d, iccSize %d",
videoFrame->mWidth, videoFrame->mWidth,
@ -391,12 +395,17 @@ bool HeifDecoderImpl::init(HeifStream* stream, HeifFrameInfo* frameInfo) {
MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC,
mOutputColor, true /*metaOnly*/); mOutputColor, true /*metaOnly*/);
if (sharedMem == nullptr || sharedMem->pointer() == nullptr) { if (sharedMem == nullptr || sharedMem->unsecurePointer() == nullptr) {
ALOGE("init: videoFrame is a nullptr"); ALOGE("init: videoFrame is a nullptr");
return false; return false;
} }
VideoFrame* videoFrame = static_cast<VideoFrame*>(sharedMem->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoFrame* videoFrame = static_cast<VideoFrame*>(
sharedMem->unsecurePointer());
ALOGV("Sequence dimension %dx%d, display %dx%d, angle %d, iccSize %d", ALOGV("Sequence dimension %dx%d, display %dx%d, angle %d, iccSize %d",
videoFrame->mWidth, videoFrame->mWidth,
@ -487,7 +496,7 @@ bool HeifDecoderImpl::decodeAsync() {
{ {
Mutex::Autolock autolock(mLock); Mutex::Autolock autolock(mLock);
if (frameMemory == nullptr || frameMemory->pointer() == nullptr) { if (frameMemory == nullptr || frameMemory->unsecurePointer() == nullptr) {
mAsyncDecodeDone = true; mAsyncDecodeDone = true;
mScanlineReady.signal(); mScanlineReady.signal();
break; break;
@ -529,12 +538,16 @@ bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {
sp<IMemory> frameMemory = mRetriever->getImageRectAtIndex( sp<IMemory> frameMemory = mRetriever->getImageRectAtIndex(
-1, mOutputColor, 0, 0, mImageInfo.mWidth, mSliceHeight); -1, mOutputColor, 0, 0, mImageInfo.mWidth, mSliceHeight);
if (frameMemory == nullptr || frameMemory->pointer() == nullptr) { if (frameMemory == nullptr || frameMemory->unsecurePointer() == nullptr) {
ALOGE("decode: metadata is a nullptr"); ALOGE("decode: metadata is a nullptr");
return false; return false;
} }
VideoFrame* videoFrame = static_cast<VideoFrame*>(frameMemory->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoFrame* videoFrame = static_cast<VideoFrame*>(frameMemory->unsecurePointer());
if (frameInfo != nullptr) { if (frameInfo != nullptr) {
initFrameInfo(frameInfo, videoFrame); initFrameInfo(frameInfo, videoFrame);
@ -563,12 +576,16 @@ bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {
MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC, mOutputColor); MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC, mOutputColor);
} }
if (mFrameMemory == nullptr || mFrameMemory->pointer() == nullptr) { if (mFrameMemory == nullptr || mFrameMemory->unsecurePointer() == nullptr) {
ALOGE("decode: videoFrame is a nullptr"); ALOGE("decode: videoFrame is a nullptr");
return false; return false;
} }
VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->unsecurePointer());
if (videoFrame->mSize == 0 || if (videoFrame->mSize == 0 ||
mFrameMemory->size() < videoFrame->getFlattenedSize()) { mFrameMemory->size() < videoFrame->getFlattenedSize()) {
ALOGE("decode: videoFrame size is invalid"); ALOGE("decode: videoFrame size is invalid");
@ -613,12 +630,16 @@ bool HeifDecoderImpl::decodeSequence(int frameIndex, HeifFrameInfo* frameInfo) {
mTotalScanline = mSequenceInfo.mHeight; mTotalScanline = mSequenceInfo.mHeight;
mFrameMemory = mRetriever->getFrameAtIndex(frameIndex, mOutputColor); mFrameMemory = mRetriever->getFrameAtIndex(frameIndex, mOutputColor);
if (mFrameMemory == nullptr || mFrameMemory->pointer() == nullptr) { if (mFrameMemory == nullptr || mFrameMemory->unsecurePointer() == nullptr) {
ALOGE("decode: videoFrame is a nullptr"); ALOGE("decode: videoFrame is a nullptr");
return false; return false;
} }
VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->unsecurePointer());
if (videoFrame->mSize == 0 || if (videoFrame->mSize == 0 ||
mFrameMemory->size() < videoFrame->getFlattenedSize()) { mFrameMemory->size() < videoFrame->getFlattenedSize()) {
ALOGE("decode: videoFrame size is invalid"); ALOGE("decode: videoFrame size is invalid");
@ -641,10 +662,14 @@ bool HeifDecoderImpl::decodeSequence(int frameIndex, HeifFrameInfo* frameInfo) {
} }
bool HeifDecoderImpl::getScanlineInner(uint8_t* dst) { bool HeifDecoderImpl::getScanlineInner(uint8_t* dst) {
if (mFrameMemory == nullptr || mFrameMemory->pointer() == nullptr) { if (mFrameMemory == nullptr || mFrameMemory->unsecurePointer() == nullptr) {
return false; return false;
} }
VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->unsecurePointer());
uint8_t* src = videoFrame->getFlattenedData() + videoFrame->mRowBytes * mCurScanline++; uint8_t* src = videoFrame->getFlattenedData() + videoFrame->mRowBytes * mCurScanline++;
memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mWidth); memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mWidth);
return true; return true;

@ -128,12 +128,12 @@ struct BpMediaHTTPConnection : public BpInterface<IMediaHTTPConnection> {
ALOGE("readAt got a NULL buffer"); ALOGE("readAt got a NULL buffer");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
if (mMemory->pointer() == NULL) { if (mMemory->unsecurePointer() == NULL) {
ALOGE("readAt got a NULL mMemory->pointer()"); ALOGE("readAt got a NULL mMemory->unsecurePointer()");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
memcpy(buffer, mMemory->pointer(), len); memcpy(buffer, mMemory->unsecurePointer(), len);
return len; return len;
} }

@ -292,7 +292,7 @@ sp<IMemory> MetadataRetrieverClient::extractAlbumArt()
delete albumArt; delete albumArt;
return NULL; return NULL;
} }
MediaAlbumArt::init((MediaAlbumArt *) mAlbumArt->pointer(), MediaAlbumArt::init((MediaAlbumArt *) mAlbumArt->unsecurePointer(),
albumArt->size(), albumArt->data()); albumArt->size(), albumArt->data());
delete albumArt; // We've taken our copy. delete albumArt; // We've taken our copy.
return mAlbumArt; return mAlbumArt;

@ -154,7 +154,7 @@ ssize_t NuPlayer::NuPlayerStreamListener::read(
} }
memcpy(data, memcpy(data,
(const uint8_t *)mem->pointer() (const uint8_t *)mem->unsecurePointer()
+ entry->mOffset, + entry->mOffset,
copy); copy);

@ -45,7 +45,12 @@ Reader::Reader(const void *shared, size_t size, const std::string &name)
} }
Reader::Reader(const sp<IMemory>& iMemory, size_t size, const std::string &name) Reader::Reader(const sp<IMemory>& iMemory, size_t size, const std::string &name)
: Reader(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL, size, name) // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
: Reader(iMemory != 0 ? (Shared *) iMemory->unsecurePointer() : NULL, size,
name)
{ {
mIMemory = iMemory; mIMemory = iMemory;
} }
@ -156,7 +161,8 @@ std::unique_ptr<Snapshot> Reader::getSnapshot(bool flush)
bool Reader::isIMemory(const sp<IMemory>& iMemory) const bool Reader::isIMemory(const sp<IMemory>& iMemory) const
{ {
return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer(); return iMemory != 0 && mIMemory != 0 &&
iMemory->unsecurePointer() == mIMemory->unsecurePointer();
} }
// We make a set of the invalid types rather than the valid types when aligning // We make a set of the invalid types rather than the valid types when aligning

@ -56,7 +56,11 @@ Writer::Writer(void *shared, size_t size)
} }
Writer::Writer(const sp<IMemory>& iMemory, size_t size) Writer::Writer(const sp<IMemory>& iMemory, size_t size)
: Writer(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL, size) // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
: Writer(iMemory != 0 ? (Shared *) iMemory->unsecurePointer() : NULL, size)
{ {
mIMemory = iMemory; mIMemory = iMemory;
} }

@ -153,7 +153,8 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(
} }
if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result); memcpy(it->mCodecBuffer->base(),
destination.mSharedMemory->unsecurePointer(), result);
} }
} else { } else {
// Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
@ -219,7 +220,8 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(
if (dstBuffer.type == BufferType::SHARED_MEMORY) { if (dstBuffer.type == BufferType::SHARED_MEMORY) {
memcpy(it->mCodecBuffer->base(), memcpy(it->mCodecBuffer->base(),
(uint8_t*)it->mSharedEncryptedBuffer->pointer(), result); (uint8_t*)it->mSharedEncryptedBuffer->unsecurePointer(),
result);
} }
} }

@ -32,7 +32,11 @@ namespace android {
// SharedMemoryBuffer // SharedMemoryBuffer
SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<IMemory> &mem) SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<IMemory> &mem)
: MediaCodecBuffer(format, new ABuffer(mem->pointer(), mem->size())), // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
: MediaCodecBuffer(format, new ABuffer(mem->unsecurePointer(), mem->size())),
mMemory(mem) { mMemory(mem) {
} }

@ -81,7 +81,8 @@ ssize_t CallbackDataSource::readAt(off64_t offset, void* data, size_t size) {
return ERROR_OUT_OF_RANGE; return ERROR_OUT_OF_RANGE;
} }
CHECK(numRead >= 0 && (size_t)numRead <= bufferSize); CHECK(numRead >= 0 && (size_t)numRead <= bufferSize);
memcpy(((uint8_t*)data) + totalNumRead, mMemory->pointer(), numRead); memcpy(((uint8_t*)data) + totalNumRead, mMemory->unsecurePointer(),
numRead);
numLeft -= numRead; numLeft -= numRead;
totalNumRead += numRead; totalNumRead += numRead;
} }

@ -89,7 +89,7 @@ void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr, void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
camera_frame_metadata_t * /* metadata */) { camera_frame_metadata_t * /* metadata */) {
ALOGV("postData(%d, ptr:%p, size:%zu)", ALOGV("postData(%d, ptr:%p, size:%zu)",
msgType, dataPtr->pointer(), dataPtr->size()); msgType, dataPtr->unsecurePointer(), dataPtr->size());
sp<CameraSource> source = mSource.promote(); sp<CameraSource> source = mSource.promote();
if (source.get() != NULL) { if (source.get() != NULL) {
@ -966,8 +966,12 @@ void CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
// Check if frame contains a VideoNativeHandleMetadata. // Check if frame contains a VideoNativeHandleMetadata.
if (frame->size() == sizeof(VideoNativeHandleMetadata)) { if (frame->size() == sizeof(VideoNativeHandleMetadata)) {
VideoNativeHandleMetadata *metadata = // TODO: Using unsecurePointer() has some associated security pitfalls
(VideoNativeHandleMetadata*)(frame->pointer()); // (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata *metadata =
(VideoNativeHandleMetadata*)(frame->unsecurePointer());
if (metadata->eType == kMetadataBufferTypeNativeHandleSource) { if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
handle = metadata->pHandle; handle = metadata->pHandle;
} }
@ -1047,7 +1051,7 @@ void CameraSource::signalBufferReturned(MediaBufferBase *buffer) {
Mutex::Autolock autoLock(mLock); Mutex::Autolock autoLock(mLock);
for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin();
it != mFramesBeingEncoded.end(); ++it) { it != mFramesBeingEncoded.end(); ++it) {
if ((*it)->pointer() == buffer->data()) { if ((*it)->unsecurePointer() == buffer->data()) {
releaseOneRecordingFrame((*it)); releaseOneRecordingFrame((*it));
mFramesBeingEncoded.erase(it); mFramesBeingEncoded.erase(it);
++mNumFramesEncoded; ++mNumFramesEncoded;
@ -1102,7 +1106,11 @@ status_t CameraSource::read(
frameTime = *mFrameTimes.begin(); frameTime = *mFrameTimes.begin();
mFrameTimes.erase(mFrameTimes.begin()); mFrameTimes.erase(mFrameTimes.begin());
mFramesBeingEncoded.push_back(frame); mFramesBeingEncoded.push_back(frame);
*buffer = new MediaBuffer(frame->pointer(), frame->size()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
*buffer = new MediaBuffer(frame->unsecurePointer(), frame->size());
(*buffer)->setObserver(this); (*buffer)->setObserver(this);
(*buffer)->add_ref(); (*buffer)->add_ref();
(*buffer)->meta_data().setInt64(kKeyTime, frameTime); (*buffer)->meta_data().setInt64(kKeyTime, frameTime);
@ -1248,7 +1256,7 @@ void CameraSource::recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
mMemoryBases.erase(mMemoryBases.begin()); mMemoryBases.erase(mMemoryBases.begin());
// Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived. // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived.
VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->pointer()); VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->unsecurePointer());
metadata->eType = kMetadataBufferTypeNativeHandleSource; metadata->eType = kMetadataBufferTypeNativeHandleSource;
metadata->pHandle = handle; metadata->pHandle = handle;
@ -1296,7 +1304,11 @@ void CameraSource::recordingFrameHandleCallbackTimestampBatch(
mMemoryBases.erase(mMemoryBases.begin()); mMemoryBases.erase(mMemoryBases.begin());
// Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived. // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived.
VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->unsecurePointer());
metadata->eType = kMetadataBufferTypeNativeHandleSource; metadata->eType = kMetadataBufferTypeNativeHandleSource;
metadata->pHandle = handle; metadata->pHandle = handle;

@ -245,11 +245,11 @@ sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
ALOGV("createIMemoryCopy"); ALOGV("createIMemoryCopy");
size_t source_size = source_data->size(); size_t source_size = source_data->size();
void* source_pointer = source_data->pointer(); void* source_pointer = source_data->unsecurePointer();
sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size); sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size);
sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size); sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size);
memcpy(newMemory->pointer(), source_pointer, source_size); memcpy(newMemory->unsecurePointer(), source_pointer, source_size);
return newMemory; return newMemory;
} }

@ -99,7 +99,7 @@ sp<IMemory> allocVideoFrame(const sp<MetaData>& trackMeta,
ALOGE("not enough memory for VideoFrame size=%zu", size); ALOGE("not enough memory for VideoFrame size=%zu", size);
return NULL; return NULL;
} }
VideoFrame* frameCopy = static_cast<VideoFrame*>(frameMem->pointer()); VideoFrame* frameCopy = static_cast<VideoFrame*>(frameMem->unsecurePointer());
frameCopy->init(frame, iccData, iccSize); frameCopy->init(frame, iccData, iccSize);
return frameMem; return frameMem;
@ -206,7 +206,7 @@ sp<IMemory> FrameDecoder::getMetadataOnly(
// try to fill sequence meta's duration based on average frame rate, // try to fill sequence meta's duration based on average frame rate,
// default to 33ms if frame rate is unavailable. // default to 33ms if frame rate is unavailable.
int32_t frameRate; int32_t frameRate;
VideoFrame* meta = static_cast<VideoFrame*>(metaMem->pointer()); VideoFrame* meta = static_cast<VideoFrame*>(metaMem->unsecurePointer());
if (trackMeta->findInt32(kKeyFrameRate, &frameRate) && frameRate > 0) { if (trackMeta->findInt32(kKeyFrameRate, &frameRate) && frameRate > 0) {
meta->mDurationUs = 1000000LL / frameRate; meta->mDurationUs = 1000000LL / frameRate;
} else { } else {
@ -614,7 +614,7 @@ status_t VideoFrameDecoder::onOutputReceived(
0, 0,
dstBpp(), dstBpp(),
mSurfaceControl != nullptr /*allocRotated*/); mSurfaceControl != nullptr /*allocRotated*/);
mFrame = static_cast<VideoFrame*>(frameMem->pointer()); mFrame = static_cast<VideoFrame*>(frameMem->unsecurePointer());
setFrame(frameMem); setFrame(frameMem);
} }
@ -895,7 +895,7 @@ status_t ImageDecoder::onOutputReceived(
if (mFrame == NULL) { if (mFrame == NULL) {
sp<IMemory> frameMem = allocVideoFrame( sp<IMemory> frameMem = allocVideoFrame(
trackMeta(), mWidth, mHeight, mTileWidth, mTileHeight, dstBpp()); trackMeta(), mWidth, mHeight, mTileWidth, mTileHeight, dstBpp());
mFrame = static_cast<VideoFrame*>(frameMem->pointer()); mFrame = static_cast<VideoFrame*>(frameMem->unsecurePointer());
setFrame(frameMem); setFrame(frameMem);
} }

@ -158,7 +158,11 @@ MediaAlbumArt *StagefrightMediaScanner::extractAlbumArt(int fd) {
if (mRetriever->setDataSource(fd, 0, size) == OK) { if (mRetriever->setDataSource(fd, 0, size) == OK) {
sp<IMemory> mem = mRetriever->extractAlbumArt(); sp<IMemory> mem = mRetriever->extractAlbumArt();
if (mem != NULL) { if (mem != NULL) {
MediaAlbumArt *art = static_cast<MediaAlbumArt *>(mem->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
MediaAlbumArt *art = static_cast<MediaAlbumArt *>(mem->unsecurePointer());
return art->clone(); return art->clone();
} }
} }

@ -72,7 +72,7 @@ MediaBuffer::MediaBuffer(size_t size)
} }
} else { } else {
getSharedControl()->clear(); getSharedControl()->clear();
mData = (uint8_t *)mMemory->pointer() + sizeof(SharedControl); mData = (uint8_t *)mMemory->unsecurePointer() + sizeof(SharedControl);
ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData); ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
} }
} }

@ -75,7 +75,7 @@ void MediaBufferGroup::init(size_t buffers, size_t buffer_size, size_t growthLim
for (size_t i = 0; i < buffers; ++i) { for (size_t i = 0; i < buffers; ++i) {
sp<IMemory> mem = memoryDealer->allocate(augmented_size); sp<IMemory> mem = memoryDealer->allocate(augmented_size);
if (mem.get() == nullptr || mem->pointer() == nullptr) { if (mem.get() == nullptr || mem->unsecurePointer() == nullptr) {
ALOGW("Only allocated %zu shared buffers of size %zu", i, buffer_size); ALOGW("Only allocated %zu shared buffers of size %zu", i, buffer_size);
break; break;
} }

@ -48,7 +48,11 @@ public:
explicit MediaBuffer(const sp<ABuffer> &buffer); explicit MediaBuffer(const sp<ABuffer> &buffer);
#ifndef NO_IMEMORY #ifndef NO_IMEMORY
MediaBuffer(const sp<IMemory> &mem) : MediaBuffer(const sp<IMemory> &mem) :
MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) { // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
MediaBuffer((uint8_t *)mem->unsecurePointer() + sizeof(SharedControl), mem->size()) {
// delegate and override mMemory // delegate and override mMemory
mMemory = mem; mMemory = mem;
} }
@ -94,9 +98,13 @@ public:
virtual int remoteRefcount() const { virtual int remoteRefcount() const {
#ifndef NO_IMEMORY #ifndef NO_IMEMORY
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0; // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
if (mMemory.get() == nullptr || mMemory->unsecurePointer() == nullptr) return 0;
int32_t remoteRefcount = int32_t remoteRefcount =
reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount(); reinterpret_cast<SharedControl *>(mMemory->unsecurePointer())->getRemoteRefcount();
// Sanity check so that remoteRefCount() is non-negative. // Sanity check so that remoteRefCount() is non-negative.
return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data. return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
#else #else
@ -107,8 +115,12 @@ public:
// returns old value // returns old value
int addRemoteRefcount(int32_t value) { int addRemoteRefcount(int32_t value) {
#ifndef NO_IMEMORY #ifndef NO_IMEMORY
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0; // TODO: Using unsecurePointer() has some associated security pitfalls
return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value); // (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
if (mMemory.get() == nullptr || mMemory->unsecurePointer() == nullptr) return 0;
return reinterpret_cast<SharedControl *>(mMemory->unsecurePointer())->addRemoteRefcount(value);
#else #else
(void) value; (void) value;
return 0; return 0;
@ -121,8 +133,12 @@ public:
static bool isDeadObject(const sp<IMemory> &memory) { static bool isDeadObject(const sp<IMemory> &memory) {
#ifndef NO_IMEMORY #ifndef NO_IMEMORY
if (memory.get() == nullptr || memory->pointer() == nullptr) return false; // TODO: Using unsecurePointer() has some associated security pitfalls
return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject(); // (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
if (memory.get() == nullptr || memory->unsecurePointer() == nullptr) return false;
return reinterpret_cast<SharedControl *>(memory->unsecurePointer())->isDeadObject();
#else #else
(void) memory; (void) memory;
return false; return false;
@ -220,7 +236,11 @@ private:
inline SharedControl *getSharedControl() const { inline SharedControl *getSharedControl() const {
#ifndef NO_IMEMORY #ifndef NO_IMEMORY
return reinterpret_cast<SharedControl *>(mMemory->pointer()); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
return reinterpret_cast<SharedControl *>(mMemory->unsecurePointer());
#else #else
return nullptr; return nullptr;
#endif #endif

@ -48,7 +48,7 @@ public:
if (size > kBufferSize) { if (size > kBufferSize) {
size = kBufferSize; size = kBufferSize;
} }
return mSource->readAt(offset, mMemory->pointer(), size); return mSource->readAt(offset, mMemory->unsecurePointer(), size);
} }
virtual status_t getSize(off64_t *size) { virtual status_t getSize(off64_t *size) {
return mSource->getSize(size); return mSource->getSize(size);

@ -128,7 +128,7 @@ struct BufferMeta {
} }
OMX_U8 *getPointer() { OMX_U8 *getPointer() {
return mMem.get() ? static_cast<OMX_U8*>(mMem->pointer()) : return mMem.get() ? static_cast<OMX_U8*>(mMem->unsecurePointer()) :
mHidlMemory.get() ? static_cast<OMX_U8*>( mHidlMemory.get() ? static_cast<OMX_U8*>(
static_cast<void*>(mHidlMemory->getPointer())) : nullptr; static_cast<void*>(mHidlMemory->getPointer())) : nullptr;
} }
@ -1173,7 +1173,11 @@ status_t OMXNodeInstance::useBuffer_l(
return BAD_VALUE; return BAD_VALUE;
} }
if (params != NULL) { if (params != NULL) {
paramsPointer = params->pointer(); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
paramsPointer = params->unsecurePointer();
paramsSize = params->size(); paramsSize = params->size();
} else if (hParams != NULL) { } else if (hParams != NULL) {
paramsPointer = hParams->getPointer(); paramsPointer = hParams->getPointer();

@ -222,9 +222,9 @@ status_t checkIMemory(const sp<IMemory>& iMemory)
off_t size = lseek(heap->getHeapID(), 0, SEEK_END); off_t size = lseek(heap->getHeapID(), 0, SEEK_END);
lseek(heap->getHeapID(), 0, SEEK_SET); lseek(heap->getHeapID(), 0, SEEK_SET);
if (iMemory->pointer() == NULL || size < (off_t)iMemory->size()) { if (iMemory->unsecurePointer() == NULL || size < (off_t)iMemory->size()) {
ALOGE("%s check failed: pointer %p size %zu fd size %u", ALOGE("%s check failed: pointer %p size %zu fd size %u",
__FUNCTION__, iMemory->pointer(), iMemory->size(), (uint32_t)size); __FUNCTION__, iMemory->unsecurePointer(), iMemory->size(), (uint32_t)size);
return BAD_VALUE; return BAD_VALUE;
} }

@ -652,7 +652,7 @@ sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
return new NBLog::Writer(); return new NBLog::Writer();
} }
success: success:
NBLog::Shared *sharedRawPtr = (NBLog::Shared *) shared->pointer(); NBLog::Shared *sharedRawPtr = (NBLog::Shared *) shared->unsecurePointer();
new((void *) sharedRawPtr) NBLog::Shared(); // placement new here, but the corresponding new((void *) sharedRawPtr) NBLog::Shared(); // placement new here, but the corresponding
// explicit destructor not needed since it is POD // explicit destructor not needed since it is POD
sMediaLogService->registerWriter(shared, size, name); sMediaLogService->registerWriter(shared, size, name);

@ -1588,7 +1588,7 @@ AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int); int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset); mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
if (mCblkMemory == 0 || if (mCblkMemory == 0 ||
(mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer())) == NULL) { (mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->unsecurePointer())) == NULL) {
ALOGE("not enough memory for Effect size=%zu", EFFECT_PARAM_BUFFER_SIZE + ALOGE("not enough memory for Effect size=%zu", EFFECT_PARAM_BUFFER_SIZE +
sizeof(effect_param_cblk_t)); sizeof(effect_param_cblk_t));
mCblkMemory.clear(); mCblkMemory.clear();

@ -2079,9 +2079,9 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
// More than 2 channels does not require stronger alignment than stereo // More than 2 channels does not require stronger alignment than stereo
alignment <<= 1; alignment <<= 1;
} }
if (((uintptr_t)sharedBuffer->pointer() & (alignment - 1)) != 0) { if (((uintptr_t)sharedBuffer->unsecurePointer() & (alignment - 1)) != 0) {
ALOGE("Invalid buffer alignment: address %p, channel count %u", ALOGE("Invalid buffer alignment: address %p, channel count %u",
sharedBuffer->pointer(), channelCount); sharedBuffer->unsecurePointer(), channelCount);
lStatus = BAD_VALUE; lStatus = BAD_VALUE;
goto Exit; goto Exit;
} }
@ -6756,7 +6756,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
sp<IMemory> pipeMemory; sp<IMemory> pipeMemory;
if ((roHeap == 0) || if ((roHeap == 0) ||
(pipeMemory = roHeap->allocate(pipeSize)) == 0 || (pipeMemory = roHeap->allocate(pipeSize)) == 0 ||
(pipeBuffer = pipeMemory->pointer()) == nullptr) { (pipeBuffer = pipeMemory->unsecurePointer()) == nullptr) {
ALOGE("not enough memory for pipe buffer size=%zu; " ALOGE("not enough memory for pipe buffer size=%zu; "
"roHeap=%p, pipeMemory=%p, pipeBuffer=%p; roHeapSize: %lld", "roHeap=%p, pipeMemory=%p, pipeBuffer=%p; roHeapSize: %lld",
pipeSize, roHeap.get(), pipeMemory.get(), pipeBuffer, pipeSize, roHeap.get(), pipeMemory.get(), pipeBuffer,

@ -150,7 +150,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
if (client != 0) { if (client != 0) {
mCblkMemory = client->heap()->allocate(size); mCblkMemory = client->heap()->allocate(size);
if (mCblkMemory == 0 || if (mCblkMemory == 0 ||
(mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) { (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->unsecurePointer())) == NULL) {
ALOGE("%s(%d): not enough memory for AudioTrack size=%zu", __func__, mId, size); ALOGE("%s(%d): not enough memory for AudioTrack size=%zu", __func__, mId, size);
client->heap()->dump("AudioTrack"); client->heap()->dump("AudioTrack");
mCblkMemory.clear(); mCblkMemory.clear();
@ -172,7 +172,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
const sp<MemoryDealer> roHeap(thread->readOnlyHeap()); const sp<MemoryDealer> roHeap(thread->readOnlyHeap());
if (roHeap == 0 || if (roHeap == 0 ||
(mBufferMemory = roHeap->allocate(bufferSize)) == 0 || (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
(mBuffer = mBufferMemory->pointer()) == NULL) { (mBuffer = mBufferMemory->unsecurePointer()) == NULL) {
ALOGE("%s(%d): not enough memory for read-only buffer size=%zu", ALOGE("%s(%d): not enough memory for read-only buffer size=%zu",
__func__, mId, bufferSize); __func__, mId, bufferSize);
if (roHeap != 0) { if (roHeap != 0) {
@ -187,7 +187,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
case ALLOC_PIPE: case ALLOC_PIPE:
mBufferMemory = thread->pipeMemory(); mBufferMemory = thread->pipeMemory();
// mBuffer is the virtual address as seen from current process (mediaserver), // mBuffer is the virtual address as seen from current process (mediaserver),
// and should normally be coming from mBufferMemory->pointer(). // and should normally be coming from mBufferMemory->unsecurePointer().
// However in this case the TrackBase does not reference the buffer directly. // However in this case the TrackBase does not reference the buffer directly.
// It should references the buffer via the pipe. // It should references the buffer via the pipe.
// Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL. // Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
@ -510,7 +510,11 @@ AudioFlinger::PlaybackThread::Track::Track(
track_type type, track_type type,
audio_port_handle_t portId) audio_port_handle_t portId)
: TrackBase(thread, client, attr, sampleRate, format, channelMask, frameCount, : TrackBase(thread, client, attr, sampleRate, format, channelMask, frameCount,
(sharedBuffer != 0) ? sharedBuffer->pointer() : buffer, // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
(sharedBuffer != 0) ? sharedBuffer->unsecurePointer() : buffer,
(sharedBuffer != 0) ? sharedBuffer->size() : bufferSize, (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
sessionId, creatorPid, uid, true /*isOut*/, sessionId, creatorPid, uid, true /*isOut*/,
(type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK, (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
@ -540,7 +544,7 @@ AudioFlinger::PlaybackThread::Track::Track(
ALOG_ASSERT(!(client == 0 && sharedBuffer != 0)); ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
ALOGV_IF(sharedBuffer != 0, "%s(%d): sharedBuffer: %p, size: %zu", ALOGV_IF(sharedBuffer != 0, "%s(%d): sharedBuffer: %p, size: %zu",
__func__, mId, sharedBuffer->pointer(), sharedBuffer->size()); __func__, mId, sharedBuffer->unsecurePointer(), sharedBuffer->size());
if (mCblk == NULL) { if (mCblk == NULL) {
return; return;

@ -534,7 +534,7 @@ void CameraClient::releaseRecordingFrameHandle(native_handle_t *handle) {
} }
if (mHardware != nullptr) { if (mHardware != nullptr) {
VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer()); VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->unsecurePointer());
metadata->eType = kMetadataBufferTypeNativeHandleSource; metadata->eType = kMetadataBufferTypeNativeHandleSource;
metadata->pHandle = handle; metadata->pHandle = handle;
mHardware->releaseRecordingFrame(dataPtr); mHardware->releaseRecordingFrame(dataPtr);
@ -573,7 +573,7 @@ void CameraClient::releaseRecordingFrameHandleBatch(const std::vector<native_han
} }
if (!disconnected) { if (!disconnected) {
VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer()); VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->unsecurePointer());
metadata->eType = kMetadataBufferTypeNativeHandleSource; metadata->eType = kMetadataBufferTypeNativeHandleSource;
metadata->pHandle = handle; metadata->pHandle = handle;
frames.push_back(dataPtr); frames.push_back(dataPtr);
@ -916,8 +916,12 @@ void CameraClient::handleCallbackTimestampBatch(
ALOGE("%s: dataPtr does not contain VideoNativeHandleMetadata!", __FUNCTION__); ALOGE("%s: dataPtr does not contain VideoNativeHandleMetadata!", __FUNCTION__);
return; return;
} }
// TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata *metadata = VideoNativeHandleMetadata *metadata =
(VideoNativeHandleMetadata*)(msg.dataPtr->pointer()); (VideoNativeHandleMetadata*)(msg.dataPtr->unsecurePointer());
if (metadata->eType == kMetadataBufferTypeNativeHandleSource) { if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
handle = metadata->pHandle; handle = metadata->pHandle;
} }
@ -1073,8 +1077,12 @@ void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
// Check if dataPtr contains a VideoNativeHandleMetadata. // Check if dataPtr contains a VideoNativeHandleMetadata.
if (dataPtr->size() == sizeof(VideoNativeHandleMetadata)) { if (dataPtr->size() == sizeof(VideoNativeHandleMetadata)) {
// TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata *metadata = VideoNativeHandleMetadata *metadata =
(VideoNativeHandleMetadata*)(dataPtr->pointer()); (VideoNativeHandleMetadata*)(dataPtr->unsecurePointer());
if (metadata->eType == kMetadataBufferTypeNativeHandleSource) { if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
handle = metadata->pHandle; handle = metadata->pHandle;
} }

@ -165,8 +165,12 @@ hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
mem = mHidlMemPoolMap.at(data); mem = mHidlMemPoolMap.at(data);
} }
sp<CameraHeapMemory> heapMem(static_cast<CameraHeapMemory *>(mem->handle)); sp<CameraHeapMemory> heapMem(static_cast<CameraHeapMemory *>(mem->handle));
// TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
heapMem->mBuffers[bufferIndex]->pointer(); heapMem->mBuffers[bufferIndex]->unsecurePointer();
md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle()); md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this); sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
return hardware::Void(); return hardware::Void();
@ -192,8 +196,12 @@ hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
hidl_msg.bufferIndex, mem->mNumBufs); hidl_msg.bufferIndex, mem->mNumBufs);
return hardware::Void(); return hardware::Void();
} }
// TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
mem->mBuffers[hidl_msg.bufferIndex]->pointer(); mem->mBuffers[hidl_msg.bufferIndex]->unsecurePointer();
md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle()); md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]}); msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
@ -578,7 +586,11 @@ void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
int bufferIndex = offset / size; int bufferIndex = offset / size;
if (CC_LIKELY(mHidlDevice != nullptr)) { if (CC_LIKELY(mHidlDevice != nullptr)) {
if (size == sizeof(VideoNativeHandleMetadata)) { if (size == sizeof(VideoNativeHandleMetadata)) {
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer(); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->unsecurePointer();
// Caching the handle here because md->pHandle will be subject to HAL's edit // Caching the handle here because md->pHandle will be subject to HAL's edit
native_handle_t* nh = md->pHandle; native_handle_t* nh = md->pHandle;
hidl_handle frame = nh; hidl_handle frame = nh;
@ -605,7 +617,11 @@ void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IM
if (size == sizeof(VideoNativeHandleMetadata)) { if (size == sizeof(VideoNativeHandleMetadata)) {
uint32_t heapId = heap->getHeapID(); uint32_t heapId = heap->getHeapID();
uint32_t bufferIndex = offset / size; uint32_t bufferIndex = offset / size;
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer(); // TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->unsecurePointer();
// Caching the handle here because md->pHandle will be subject to HAL's edit // Caching the handle here because md->pHandle will be subject to HAL's edit
native_handle_t* nh = md->pHandle; native_handle_t* nh = md->pHandle;
VideoFrameMessage msg; VideoFrameMessage msg;

@ -234,11 +234,11 @@ sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
size_t size = event->data_offset + event->data_size; size_t size = event->data_offset + event->data_size;
eventMemory = mMemoryDealer->allocate(size); eventMemory = mMemoryDealer->allocate(size);
if (eventMemory == 0 || eventMemory->pointer() == NULL) { if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
eventMemory.clear(); eventMemory.clear();
return eventMemory; return eventMemory;
} }
memcpy(eventMemory->pointer(), event, size); memcpy(eventMemory->unsecurePointer(), event, size);
return eventMemory; return eventMemory;
} }
@ -283,11 +283,11 @@ sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_m
size_t size = event->data_offset + event->data_size; size_t size = event->data_offset + event->data_size;
eventMemory = mMemoryDealer->allocate(size); eventMemory = mMemoryDealer->allocate(size);
if (eventMemory == 0 || eventMemory->pointer() == NULL) { if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
eventMemory.clear(); eventMemory.clear();
return eventMemory; return eventMemory;
} }
memcpy(eventMemory->pointer(), event, size); memcpy(eventMemory->unsecurePointer(), event, size);
return eventMemory; return eventMemory;
} }
@ -313,11 +313,11 @@ sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_servic
size_t size = sizeof(sound_trigger_service_state_t); size_t size = sizeof(sound_trigger_service_state_t);
eventMemory = mMemoryDealer->allocate(size); eventMemory = mMemoryDealer->allocate(size);
if (eventMemory == 0 || eventMemory->pointer() == NULL) { if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
eventMemory.clear(); eventMemory.clear();
return eventMemory; return eventMemory;
} }
*((sound_trigger_service_state_t *)eventMemory->pointer()) = state; *((sound_trigger_service_state_t *)eventMemory->unsecurePointer()) = state;
return eventMemory; return eventMemory;
} }
@ -557,8 +557,12 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelM
return NO_INIT; return NO_INIT;
} }
// TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
struct sound_trigger_sound_model *sound_model = struct sound_trigger_sound_model *sound_model =
(struct sound_trigger_sound_model *)modelMemory->pointer(); (struct sound_trigger_sound_model *)modelMemory->unsecurePointer();
size_t structSize; size_t structSize;
if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
@ -651,8 +655,12 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha
return NO_INIT; return NO_INIT;
} }
// TODO: Using unsecurePointer() has some associated security pitfalls
// (see declaration for details).
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
struct sound_trigger_recognition_config *config = struct sound_trigger_recognition_config *config =
(struct sound_trigger_recognition_config *)dataMemory->pointer(); (struct sound_trigger_recognition_config *)dataMemory->unsecurePointer();
if (config->data_offset < sizeof(struct sound_trigger_recognition_config) || if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
config->data_size > (UINT_MAX - config->data_offset) || config->data_size > (UINT_MAX - config->data_offset) ||
@ -734,9 +742,10 @@ void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& eve
{ {
ALOGV("onCallbackEvent type %d", event->mType); ALOGV("onCallbackEvent type %d", event->mType);
// Memory is coming from a trusted process.
sp<IMemory> eventMemory = event->mMemory; sp<IMemory> eventMemory = event->mMemory;
if (eventMemory == 0 || eventMemory->pointer() == NULL) { if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
return; return;
} }
if (mModuleClients.isEmpty()) { if (mModuleClients.isEmpty()) {
@ -749,7 +758,7 @@ void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& eve
switch (event->mType) { switch (event->mType) {
case CallbackEvent::TYPE_RECOGNITION: { case CallbackEvent::TYPE_RECOGNITION: {
struct sound_trigger_recognition_event *recognitionEvent = struct sound_trigger_recognition_event *recognitionEvent =
(struct sound_trigger_recognition_event *)eventMemory->pointer(); (struct sound_trigger_recognition_event *)eventMemory->unsecurePointer();
{ {
AutoMutex lock(mLock); AutoMutex lock(mLock);
sp<Model> model = getModel(recognitionEvent->model); sp<Model> model = getModel(recognitionEvent->model);
@ -769,7 +778,7 @@ void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& eve
} break; } break;
case CallbackEvent::TYPE_SOUNDMODEL: { case CallbackEvent::TYPE_SOUNDMODEL: {
struct sound_trigger_model_event *soundmodelEvent = struct sound_trigger_model_event *soundmodelEvent =
(struct sound_trigger_model_event *)eventMemory->pointer(); (struct sound_trigger_model_event *)eventMemory->unsecurePointer();
{ {
AutoMutex lock(mLock); AutoMutex lock(mLock);
sp<Model> model = getModel(soundmodelEvent->model); sp<Model> model = getModel(soundmodelEvent->model);
@ -1082,7 +1091,8 @@ void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent
sp<IMemory> eventMemory = event->mMemory; sp<IMemory> eventMemory = event->mMemory;
if (eventMemory == 0 || eventMemory->pointer() == NULL) { // Memory is coming from a trusted process.
if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
return; return;
} }

@ -204,39 +204,42 @@ status_t SoundTrigger::getModelState(sound_model_handle_t handle)
void SoundTrigger::onRecognitionEvent(const sp<IMemory>& eventMemory) void SoundTrigger::onRecognitionEvent(const sp<IMemory>& eventMemory)
{ {
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
if (eventMemory == 0 || eventMemory->pointer() == NULL) { if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
return; return;
} }
if (mCallback != 0) { if (mCallback != 0) {
// Memory is coming from a trusted process.
mCallback->onRecognitionEvent( mCallback->onRecognitionEvent(
(struct sound_trigger_recognition_event *)eventMemory->pointer()); (struct sound_trigger_recognition_event *)eventMemory->unsecurePointer());
} }
} }
void SoundTrigger::onSoundModelEvent(const sp<IMemory>& eventMemory) void SoundTrigger::onSoundModelEvent(const sp<IMemory>& eventMemory)
{ {
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
if (eventMemory == 0 || eventMemory->pointer() == NULL) { if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
return; return;
} }
if (mCallback != 0) { if (mCallback != 0) {
// Memory is coming from a trusted process.
mCallback->onSoundModelEvent( mCallback->onSoundModelEvent(
(struct sound_trigger_model_event *)eventMemory->pointer()); (struct sound_trigger_model_event *)eventMemory->unsecurePointer());
} }
} }
void SoundTrigger::onServiceStateChange(const sp<IMemory>& eventMemory) void SoundTrigger::onServiceStateChange(const sp<IMemory>& eventMemory)
{ {
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
if (eventMemory == 0 || eventMemory->pointer() == NULL) { if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
return; return;
} }
if (mCallback != 0) { if (mCallback != 0) {
// Memory is coming from a trusted process.
mCallback->onServiceStateChange( mCallback->onServiceStateChange(
*((sound_trigger_service_state_t *)eventMemory->pointer())); *((sound_trigger_service_state_t *)eventMemory->unsecurePointer()));
} }
} }

Loading…
Cancel
Save