diff options
author | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2016-12-12 15:01:24 +0100 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2016-12-12 15:01:24 +0100 |
commit | e15fd68c5dc4089690b5d3086776c3851e504bb7 (patch) | |
tree | 2c75274dee02b07463c9164efdf6888e1a9c75dc /media/libmedia/IOMX.cpp | |
parent | 185e2110a53feb7720d91b6f8366ad27402f21cc (diff) | |
parent | 26c5fa31d17a638bf314de6e12e86bb8a86db44b (diff) | |
download | frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.zip frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.gz frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.bz2 |
Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_frameworks_av into replicant-6.0
Diffstat (limited to 'media/libmedia/IOMX.cpp')
-rw-r--r-- | media/libmedia/IOMX.cpp | 143 |
1 files changed, 104 insertions, 39 deletions
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 5356494..7e951c9 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -18,11 +18,14 @@ #define LOG_TAG "IOMX" #include <utils/Log.h> +#include <sys/mman.h> + #include <binder/IMemory.h> #include <binder/Parcel.h> #include <media/IOMX.h> #include <media/stagefright/foundation/ADebug.h> #include <media/AVMediaExtensions.h> +#include <media/openmax/OMX_IndexExt.h> namespace android { @@ -246,7 +249,7 @@ public: virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) { + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL /* crossProcess */) { Parcel data, reply; data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); data.writeInt32((int32_t)node); @@ -447,7 +450,7 @@ public: remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); status_t err = reply.readInt32(); - if (sidebandHandle) { + if (err == OK && sidebandHandle) { *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); } return err; @@ -480,7 +483,7 @@ public: virtual status_t allocateBufferWithBackup( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) { + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL /* crossProcess */) { Parcel data, reply; data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); data.writeInt32((int32_t)node); @@ -694,34 +697,79 @@ status_t BnOMX::onTransact( size_t size = data.readInt64(); - void *params = malloc(size); - data.read(params, size); - - status_t err; - switch (code) { - case GET_PARAMETER: - err = getParameter(node, index, params, size); - break; - case SET_PARAMETER: - err = setParameter(node, index, params, size); - break; - case GET_CONFIG: - err = getConfig(node, index, params, size); - break; - case SET_CONFIG: - err = setConfig(node, index, params, size); - break; - case SET_INTERNAL_OPTION: - { - InternalOptionType type = - (InternalOptionType)data.readInt32(); - - err = setInternalOption(node, index, type, params, size); - break; + status_t err = NOT_ENOUGH_DATA; + void *params = NULL; + size_t pageSize = 0; + size_t allocSize = 0; + bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits); + if ((isUsageBits && size < 4) || + (!isUsageBits && code != SET_INTERNAL_OPTION && size < 8)) { + // we expect the structure to contain at least the size and + // version, 8 bytes total + ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code)); + android_errorWriteLog(0x534e4554, "27207275"); + } else { + err = NO_MEMORY; + pageSize = (size_t) sysconf(_SC_PAGE_SIZE); + if (size > SIZE_MAX - (pageSize * 2)) { + ALOGE("requested param size too big"); + } else { + allocSize = (size + pageSize * 2) & ~(pageSize - 1); + params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */); + } + if (params != MAP_FAILED) { + err = data.read(params, size); + if (err != OK) { + android_errorWriteLog(0x534e4554, "26914474"); + } else { + err = NOT_ENOUGH_DATA; + OMX_U32 declaredSize = *(OMX_U32*)params; + if (code != SET_INTERNAL_OPTION && + index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && + declaredSize > size) { + // the buffer says it's bigger than it actually is + ALOGE("b/27207275 (%u/%zu)", declaredSize, size); + android_errorWriteLog(0x534e4554, "27207275"); + } else { + // mark the last page as inaccessible, to avoid exploitation + // of codecs that access past the end of the allocation because + // they didn't check the size + if (mprotect((char*)params + allocSize - pageSize, pageSize, + PROT_NONE) != 0) { + ALOGE("mprotect failed: %s", strerror(errno)); + } else { + switch (code) { + case GET_PARAMETER: + err = getParameter(node, index, params, size); + break; + case SET_PARAMETER: + err = setParameter(node, index, params, size); + break; + case GET_CONFIG: + err = getConfig(node, index, params, size); + break; + case SET_CONFIG: + err = setConfig(node, index, params, size); + break; + case SET_INTERNAL_OPTION: + { + InternalOptionType type = + (InternalOptionType)data.readInt32(); + + err = setInternalOption(node, index, type, params, size); + break; + } + + default: + TRESPASS(); + } + } + } + } + } else { + ALOGE("couldn't map: %s", strerror(errno)); } - - default: - TRESPASS(); } reply->writeInt32(err); @@ -730,7 +778,9 @@ status_t BnOMX::onTransact( reply->write(params, size); } - free(params); + if (params) { + munmap(params, allocSize); + } params = NULL; return NO_ERROR; @@ -790,7 +840,8 @@ status_t BnOMX::onTransact( OMX_U32 allottedSize = data.readInt32(); buffer_id buffer; - status_t err = useBuffer(node, port_index, params, &buffer, allottedSize); + status_t err = useBuffer( + node, port_index, params, &buffer, allottedSize, OMX_TRUE /* crossProcess */); reply->writeInt32(err); if (err == OK) { @@ -846,9 +897,13 @@ status_t BnOMX::onTransact( OMX_U32 port_index = data.readInt32(); sp<IGraphicBufferProducer> bufferProducer; - MetadataBufferType type; + MetadataBufferType type = kMetadataBufferTypeInvalid; status_t err = createInputSurface(node, port_index, &bufferProducer, &type); + if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { + android_errorWriteLog(0x534e4554, "26324358"); + } + reply->writeInt32(type); reply->writeInt32(err); @@ -888,9 +943,13 @@ status_t BnOMX::onTransact( sp<IGraphicBufferConsumer> bufferConsumer = interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); - MetadataBufferType type; + MetadataBufferType type = kMetadataBufferTypeInvalid; status_t err = setInputSurface(node, port_index, bufferConsumer, &type); + if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { + android_errorWriteLog(0x534e4554, "26324358"); + } + reply->writeInt32(type); reply->writeInt32(err); return NO_ERROR; @@ -916,8 +975,12 @@ status_t BnOMX::onTransact( OMX_U32 port_index = data.readInt32(); OMX_BOOL enable = (OMX_BOOL)data.readInt32(); - MetadataBufferType type; - status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); + MetadataBufferType type = kMetadataBufferTypeInvalid; + status_t err = + // only control output metadata via Binder + port_index != 1 /* kOutputPortIndex */ ? BAD_VALUE : + storeMetaDataInBuffers(node, port_index, enable, &type); + reply->writeInt32(type); reply->writeInt32(err); @@ -950,11 +1013,13 @@ status_t BnOMX::onTransact( OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); OMX_U32 audio_hw_sync = data.readInt32(); - native_handle_t *sideband_handle; + native_handle_t *sideband_handle = NULL; status_t err = configureVideoTunnelMode( node, port_index, tunneled, audio_hw_sync, &sideband_handle); reply->writeInt32(err); - reply->writeNativeHandle(sideband_handle); + if(err == OK){ + reply->writeNativeHandle(sideband_handle); + } return NO_ERROR; } @@ -1000,7 +1065,7 @@ status_t BnOMX::onTransact( buffer_id buffer; status_t err = allocateBufferWithBackup( - node, port_index, params, &buffer, allottedSize); + node, port_index, params, &buffer, allottedSize, OMX_TRUE /* crossProcess */); reply->writeInt32(err); |