summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonas Kylmälä <joonas.kylmala@iki.fi>2018-08-27 13:35:19 -0400
committerJoonas Kylmälä <joonas.kylmala@iki.fi>2018-08-27 13:35:19 -0400
commite5bc488f110fd7cb70b7a78c3449476679236277 (patch)
tree978d47c3905fbdfc7e76b98e51dd4ebd73f4152d
parent6cf6309d48f3d97b6f0cd43843917664e42c32dc (diff)
parentdc3b246bb1422b805937343e65b513d246952eb6 (diff)
downloadframeworks_av-e5bc488f110fd7cb70b7a78c3449476679236277.tar.gz
frameworks_av-e5bc488f110fd7cb70b7a78c3449476679236277.tar.bz2
frameworks_av-e5bc488f110fd7cb70b7a78c3449476679236277.zip
Merge remote-tracking branch 'lineageos/cm-13.0' into replicant-6.0replicant-6.0-aug-2018
-rw-r--r--drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp5
-rw-r--r--drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h1
-rw-r--r--drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp63
-rw-r--r--include/media/IAudioPolicyService.h4
-rw-r--r--include/media/MediaPlayerInterface.h30
-rw-r--r--media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp4
-rw-r--r--media/libmedia/IAudioPolicyService.cpp77
-rw-r--r--media/libmedia/IDrm.cpp9
-rw-r--r--media/libmediaplayerservice/MediaPlayerFactory.cpp5
-rw-r--r--media/libmediaplayerservice/MediaPlayerFactory.h3
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp41
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h68
-rw-r--r--media/libstagefright/AACExtractor.cpp4
-rwxr-xr-xmedia/libstagefright/MPEG4Extractor.cpp3
-rw-r--r--media/libstagefright/VideoFrameScheduler.cpp5
-rw-r--r--media/libstagefright/avc_utils.cpp2
-rw-r--r--media/libstagefright/codecs/avcdec/SoftAVCDec.cpp10
-rw-r--r--media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp6
-rw-r--r--media/libstagefright/codecs/hevcdec/SoftHEVC.cpp8
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp2
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp8
-rw-r--r--media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp2
-rw-r--r--media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp15
-rw-r--r--media/libstagefright/httplive/M3UParser.cpp10
-rw-r--r--media/libstagefright/id3/ID3.cpp28
-rw-r--r--media/libstagefright/include/SoftVideoEncoderOMXComponent.h2
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.cpp9
-rw-r--r--media/libstagefright/omx/Android.mk4
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp4
-rw-r--r--media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp13
-rw-r--r--services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp1
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp2
-rw-r--r--services/soundtrigger/SoundTriggerHwService.cpp98
-rw-r--r--services/soundtrigger/SoundTriggerHwService.h3
34 files changed, 390 insertions, 159 deletions
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
index 01f8d65702..f7106b275e 100644
--- a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
+++ b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
@@ -36,6 +36,11 @@ android::status_t AesCtrDecryptor::decrypt(const android::Vector<uint8_t>& key,
uint8_t previousEncryptedCounter[kBlockSize];
memset(previousEncryptedCounter, 0, kBlockSize);
+ if (key.size() != kBlockSize || (sizeof(Iv) / sizeof(uint8_t)) != kBlockSize) {
+ android_errorWriteLog(0x534e4554, "63982768");
+ return android::ERROR_DRM_DECRYPT;
+ }
+
size_t offset = 0;
AES_KEY opensslKey;
AES_set_encrypt_key(key.array(), kBlockBitCount, &opensslKey);
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
index b416266ddf..edb84458a7 100644
--- a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
+++ b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
@@ -18,6 +18,7 @@
#define CLEARKEY_AES_CTR_DECRYPTOR_H_
#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaErrors.h>
#include <Utils.h>
#include <utils/Errors.h>
#include <utils/Vector.h>
diff --git a/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp b/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
index 039e40226b..5db8290a91 100644
--- a/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
+++ b/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
@@ -34,7 +34,7 @@ class AesCtrDecryptorTest : public ::testing::Test {
uint8_t* destination, const SubSample* subSamples,
size_t numSubSamples, size_t* bytesDecryptedOut) {
Vector<uint8_t> keyVector;
- keyVector.appendArray(key, kBlockSize);
+ keyVector.appendArray(key, sizeof(key) / sizeof(uint8_t));
AesCtrDecryptor decryptor;
return decryptor.decrypt(keyVector, iv, source, destination, subSamples,
@@ -57,6 +57,67 @@ class AesCtrDecryptorTest : public ::testing::Test {
}
};
+TEST_F(AesCtrDecryptorTest, DecryptsWithEmptyKey) {
+ const size_t kTotalSize = 64;
+ const size_t kNumSubsamples = 1;
+
+ // Test vectors from NIST-800-38A
+ Iv iv = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+ };
+
+ uint8_t source[kTotalSize] = { 0 };
+ uint8_t destination[kTotalSize] = { 0 };
+ SubSample subSamples[kNumSubsamples] = {
+ {0, 64}
+ };
+
+ size_t bytesDecrypted = 0;
+ Vector<uint8_t> keyVector;
+ keyVector.clear();
+
+ AesCtrDecryptor decryptor;
+ ASSERT_EQ(android::ERROR_DRM_DECRYPT, decryptor.decrypt(keyVector, iv,
+ &source[0], &destination[0],
+ &subSamples[0], kNumSubsamples, &bytesDecrypted));
+ ASSERT_EQ(0u, bytesDecrypted);
+}
+
+TEST_F(AesCtrDecryptorTest, DecryptsWithKeyTooLong) {
+ const size_t kTotalSize = 64;
+ const size_t kNumSubsamples = 1;
+
+ // Test vectors from NIST-800-38A
+ uint8_t key[kBlockSize * 2] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
+ };
+
+ Iv iv = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+ };
+
+ uint8_t source[kTotalSize] = { 0 };
+ uint8_t destination[kTotalSize] = { 0 };
+ SubSample subSamples[kNumSubsamples] = {
+ {0, 64}
+ };
+
+ size_t bytesDecrypted = 0;
+ Vector<uint8_t> keyVector;
+ keyVector.appendArray(key, sizeof(key) / sizeof(uint8_t));
+
+ AesCtrDecryptor decryptor;
+ ASSERT_EQ(android::ERROR_DRM_DECRYPT, decryptor.decrypt(keyVector, iv,
+ &source[0], &destination[0],
+ &subSamples[0], kNumSubsamples, &bytesDecrypted));
+ ASSERT_EQ(0u, bytesDecrypted);
+}
+
TEST_F(AesCtrDecryptorTest, DecryptsContiguousEncryptedBlock) {
const size_t kTotalSize = 64;
const size_t kNumSubsamples = 1;
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 1df91ee140..9441861635 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -180,6 +180,10 @@ public:
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
+private:
+ void sanetizeAudioAttributes(audio_attributes_t* attr);
+ status_t sanitizeEffectDescriptor(effect_descriptor_t* desc);
+ status_t sanitizeAudioPortConfig(struct audio_port_config* config);
};
// ----------------------------------------------------------------------------
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 4810b7eef4..875c6b685c 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -65,14 +65,17 @@ enum player_type {
// duration below which we do not allow deep audio buffering
#define AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US 5000000
-// callback mechanism for passing messages to MediaPlayer object
-typedef void (*notify_callback_f)(void* cookie,
- int msg, int ext1, int ext2, const Parcel *obj);
-
// abstract base class - use MediaPlayerInterface
class MediaPlayerBase : public RefBase
{
public:
+ // callback mechanism for passing messages to MediaPlayer object
+ class Listener : public RefBase {
+ public:
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
+ virtual ~Listener() {}
+ };
+
// AudioSink: abstraction layer for audio output
class AudioSink : public RefBase {
public:
@@ -144,7 +147,7 @@ public:
virtual String8 getParameters(const String8& /* keys */) { return String8::empty(); }
};
- MediaPlayerBase() : mCookie(0), mNotify(0) {}
+ MediaPlayerBase() {}
virtual ~MediaPlayerBase() {}
virtual status_t initCheck() = 0;
virtual bool hardwareOutput() = 0;
@@ -245,22 +248,22 @@ public:
};
void setNotifyCallback(
- void* cookie, notify_callback_f notifyFunc) {
+ const sp<Listener> &listener) {
Mutex::Autolock autoLock(mNotifyLock);
- mCookie = cookie; mNotify = notifyFunc;
+ mListener = listener;
}
void sendEvent(int msg, int ext1=0, int ext2=0,
const Parcel *obj=NULL) {
- notify_callback_f notifyCB;
- void* cookie;
+ sp<Listener> listener;
{
Mutex::Autolock autoLock(mNotifyLock);
- notifyCB = mNotify;
- cookie = mCookie;
+ listener = mListener;
}
- if (notifyCB) notifyCB(cookie, msg, ext1, ext2, obj);
+ if (listener != NULL) {
+ listener->notify(msg, ext1, ext2, obj);
+ }
}
virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const {
@@ -279,8 +282,7 @@ private:
friend class MediaPlayerService;
Mutex mNotifyLock;
- void* mCookie;
- notify_callback_f mNotify;
+ sp<Listener> mListener;
};
// Implement this class for media players that use the AudioFlinger software mixer
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 19892ddac3..80c8a3878f 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -1768,6 +1768,10 @@ int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue, in
if (param != REVERB_PARAM_PRESET) {
return -EINVAL;
}
+ if (vsize < (int)sizeof(uint16_t)) {
+ android_errorWriteLog(0x534e4554, "67647856");
+ return -EINVAL;
+ }
uint16_t preset = *(uint16_t *)pValue;
ALOGV("set REVERB_PARAM_PRESET, preset %d", preset);
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index abae614645..7a80bad7e9 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -863,7 +863,7 @@ status_t BnAudioPolicyService::onTransact(
audio_output_flags_t flags =
static_cast <audio_output_flags_t>(data.readInt32());
bool hasOffloadInfo = data.readInt32() != 0;
- audio_offload_info_t offloadInfo;
+ audio_offload_info_t offloadInfo = {};
if (hasOffloadInfo) {
data.read(&offloadInfo, sizeof(audio_offload_info_t));
}
@@ -879,10 +879,11 @@ status_t BnAudioPolicyService::onTransact(
case GET_OUTPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_attributes_t attr;
+ audio_attributes_t attr = {};
bool hasAttributes = data.readInt32() != 0;
if (hasAttributes) {
data.read(&attr, sizeof(audio_attributes_t));
+ sanetizeAudioAttributes(&attr);
}
audio_session_t session = (audio_session_t)data.readInt32();
audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
@@ -948,8 +949,9 @@ status_t BnAudioPolicyService::onTransact(
case GET_INPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_attributes_t attr;
+ audio_attributes_t attr = {};
data.read(&attr, sizeof(audio_attributes_t));
+ sanetizeAudioAttributes(&attr);
audio_session_t session = (audio_session_t)data.readInt32();
uid_t uid = (uid_t)data.readInt32();
uint32_t samplingRate = data.readInt32();
@@ -1044,8 +1046,11 @@ status_t BnAudioPolicyService::onTransact(
case GET_OUTPUT_FOR_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- effect_descriptor_t desc;
- data.read(&desc, sizeof(effect_descriptor_t));
+ effect_descriptor_t desc = {};
+ if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "73126106");
+ }
+ (void)sanitizeEffectDescriptor(&desc);
audio_io_handle_t output = getOutputForEffect(&desc);
reply->writeInt32(static_cast <int>(output));
return NO_ERROR;
@@ -1053,8 +1058,11 @@ status_t BnAudioPolicyService::onTransact(
case REGISTER_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- effect_descriptor_t desc;
- data.read(&desc, sizeof(effect_descriptor_t));
+ effect_descriptor_t desc = {};
+ if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "73126106");
+ }
+ (void)sanitizeEffectDescriptor(&desc);
audio_io_handle_t io = data.readInt32();
uint32_t strategy = data.readInt32();
int session = data.readInt32();
@@ -1113,7 +1121,7 @@ status_t BnAudioPolicyService::onTransact(
count = AudioEffect::kMaxPreProcessing;
}
uint32_t retCount = count;
- effect_descriptor_t *descriptors = new effect_descriptor_t[count];
+ effect_descriptor_t *descriptors = new effect_descriptor_t[count]{};
status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
reply->writeInt32(status);
if (status != NO_ERROR && status != NO_MEMORY) {
@@ -1132,7 +1140,7 @@ status_t BnAudioPolicyService::onTransact(
case IS_OFFLOAD_SUPPORTED: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_offload_info_t info;
+ audio_offload_info_t info = {};
data.read(&info, sizeof(audio_offload_info_t));
bool isSupported = isOffloadSupported(info);
reply->writeInt32(isSupported);
@@ -1187,7 +1195,7 @@ status_t BnAudioPolicyService::onTransact(
case CREATE_AUDIO_PATCH: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_patch patch;
+ struct audio_patch patch = {};
data.read(&patch, sizeof(struct audio_patch));
audio_patch_handle_t handle = {};
if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
@@ -1203,7 +1211,7 @@ status_t BnAudioPolicyService::onTransact(
case RELEASE_AUDIO_PATCH: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_patch_handle_t handle;
+ audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
data.read(&handle, sizeof(audio_patch_handle_t));
status_t status = releaseAudioPatch(handle);
reply->writeInt32(status);
@@ -1242,8 +1250,9 @@ status_t BnAudioPolicyService::onTransact(
case SET_AUDIO_PORT_CONFIG: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_port_config config;
+ struct audio_port_config config = {};
data.read(&config, sizeof(struct audio_port_config));
+ (void)sanitizeAudioPortConfig(&config);
status_t status = setAudioPortConfig(&config);
reply->writeInt32(status);
return NO_ERROR;
@@ -1334,10 +1343,12 @@ status_t BnAudioPolicyService::onTransact(
case START_AUDIO_SOURCE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_port_config source;
+ struct audio_port_config source = {};
data.read(&source, sizeof(struct audio_port_config));
- audio_attributes_t attributes;
+ (void)sanitizeAudioPortConfig(&source);
+ audio_attributes_t attributes = {};
data.read(&attributes, sizeof(audio_attributes_t));
+ sanetizeAudioAttributes(&attributes);
audio_io_handle_t handle = {};
status_t status = startAudioSource(&source, &attributes, &handle);
reply->writeInt32(status);
@@ -1358,6 +1369,44 @@ status_t BnAudioPolicyService::onTransact(
}
}
+/** returns true if string overflow was prevented by zero termination */
+template <size_t size>
+static bool preventStringOverflow(char (&s)[size]) {
+ if (strnlen(s, size) < size) return false;
+ s[size - 1] = '\0';
+ return true;
+}
+
+void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
+{
+ const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
+ if (strnlen(attr->tags, tagsMaxSize) >= tagsMaxSize) {
+ android_errorWriteLog(0x534e4554, "68953950"); // SafetyNet logging
+ }
+ attr->tags[tagsMaxSize - 1] = '\0';
+}
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeEffectDescriptor(effect_descriptor_t* desc)
+{
+ if (preventStringOverflow(desc->name)
+ | /* always */ preventStringOverflow(desc->implementor)) {
+ android_errorWriteLog(0x534e4554, "73126106"); // SafetyNet logging
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeAudioPortConfig(struct audio_port_config* config)
+{
+ if (config->type == AUDIO_PORT_TYPE_DEVICE &&
+ preventStringOverflow(config->ext.device.address)) {
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
} // namespace android
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index 6f6530bfe2..637770ddb5 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -572,8 +572,13 @@ IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
uint32_t size = data.readInt32();
- vector.insertAt((size_t)0, size);
- data.read(vector.editArray(), size);
+ if (vector.insertAt((size_t)0, size) < 0) {
+ vector.clear();
+ }
+ if (data.read(vector.editArray(), size) != NO_ERROR) {
+ vector.clear();
+ android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
+ }
}
void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index f0afc5a0fb..598e306de2 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -128,8 +128,7 @@ player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
player_type playerType,
- void* cookie,
- notify_callback_f notifyFunc,
+ const sp<MediaPlayerBase::Listener> &listener,
pid_t pid) {
sp<MediaPlayerBase> p;
IFactory* factory;
@@ -154,7 +153,7 @@ sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
init_result = p->initCheck();
if (init_result == NO_ERROR) {
- p->setNotifyCallback(cookie, notifyFunc);
+ p->setNotifyCallback(listener);
} else {
ALOGE("Failed to create player object of type %d, initCheck failed"
" (res = %d)", playerType, init_result);
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.h b/media/libmediaplayerservice/MediaPlayerFactory.h
index e22a56fe6e..e88700cf58 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.h
+++ b/media/libmediaplayerservice/MediaPlayerFactory.h
@@ -65,8 +65,7 @@ class MediaPlayerFactory {
const sp<DataSource> &source);
static sp<MediaPlayerBase> createPlayer(player_type playerType,
- void* cookie,
- notify_callback_f notifyFunc,
+ const sp<MediaPlayerBase::Listener> &listener,
pid_t pid);
static void registerBuiltinFactories();
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index a2ec69182e..d4a5847b41 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -604,10 +604,11 @@ MediaPlayerService::Client::Client(
mUID = uid;
mRetransmitEndpointValid = false;
mAudioAttributes = NULL;
+ mListener = new Listener(this);
#if CALLBACK_ANTAGONIZER
ALOGD("create Antagonizer");
- mAntagonizer = new Antagonizer(notify, this);
+ mAntagonizer = new Antagonizer(mListener);
#endif
}
@@ -643,7 +644,7 @@ void MediaPlayerService::Client::disconnect()
// and reset the player. We assume the player will serialize
// access to itself if necessary.
if (p != 0) {
- p->setNotifyCallback(0, 0);
+ p->setNotifyCallback(0);
#if CALLBACK_ANTAGONIZER
ALOGD("kill Antagonizer");
mAntagonizer->kill();
@@ -665,7 +666,7 @@ sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerT
p.clear();
}
if (p == NULL) {
- p = MediaPlayerFactory::createPlayer(playerType, this, notify, mPid);
+ p = MediaPlayerFactory::createPlayer(playerType, mListener, mPid);
}
if (p != NULL) {
@@ -1271,29 +1272,25 @@ status_t MediaPlayerService::Client::getRetransmitEndpoint(
}
void MediaPlayerService::Client::notify(
- void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
+ int msg, int ext1, int ext2, const Parcel *obj)
{
- Client* client = static_cast<Client*>(cookie);
- if (client == NULL) {
- return;
- }
sp<IMediaPlayerClient> c;
{
- Mutex::Autolock l(client->mLock);
- c = client->mClient;
- if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
- if (client->mAudioOutput != NULL)
- client->mAudioOutput->switchToNextOutput();
+ Mutex::Autolock l(mLock);
+ c = mClient;
+ if (msg == MEDIA_PLAYBACK_COMPLETE && mNextClient != NULL) {
+ if (mAudioOutput != NULL)
+ mAudioOutput->switchToNextOutput();
ALOGD("gapless:current track played back");
ALOGD("gapless:try to do a gapless switch to next track");
status_t ret;
- ret = client->mNextClient->start();
+ ret = mNextClient->start();
if (ret == NO_ERROR) {
- client->mNextClient->mClient->notify(MEDIA_INFO,
+ mNextClient->mClient->notify(MEDIA_INFO,
MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
} else {
- client->mClient->notify(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN , 0, obj);
+ mClient->notify(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN , 0, obj);
ALOGW("gapless:start playback for next track failed");
}
}
@@ -1303,17 +1300,17 @@ void MediaPlayerService::Client::notify(
MEDIA_INFO_METADATA_UPDATE == ext1) {
const media::Metadata::Type metadata_type = ext2;
- if(client->shouldDropMetadata(metadata_type)) {
+ if(shouldDropMetadata(metadata_type)) {
return;
}
// Update the list of metadata that have changed. getMetadata
// also access mMetadataUpdated and clears it.
- client->addNewMetadataUpdate(metadata_type);
+ addNewMetadataUpdate(metadata_type);
}
if (c != NULL) {
- ALOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
+ ALOGV("[%d] notify (%d, %d, %d)", mConnId, msg, ext1, ext2);
c->notify(msg, ext1, ext2, obj);
}
}
@@ -1361,8 +1358,8 @@ status_t MediaPlayerService::Client::resume()
#if CALLBACK_ANTAGONIZER
const int Antagonizer::interval = 10000; // 10 msecs
-Antagonizer::Antagonizer(notify_callback_f cb, void* client) :
- mExit(false), mActive(false), mClient(client), mCb(cb)
+Antagonizer::Antagonizer(const sp<MediaPlayerBase::Listener> &listener) :
+ mExit(false), mActive(false), mListener(listener)
{
createThread(callbackThread, this);
}
@@ -1382,7 +1379,7 @@ int Antagonizer::callbackThread(void* user)
while (!p->mExit) {
if (p->mActive) {
ALOGV("send event");
- p->mCb(p->mClient, 0, 0, 0);
+ p->mListener->notify(0, 0, 0, 0);
}
usleep(interval);
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 2bd7ec5c75..6e97b3892b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -49,7 +49,7 @@ class MediaRecorderClient;
#if CALLBACK_ANTAGONIZER
class Antagonizer {
public:
- Antagonizer(notify_callback_f cb, void* client);
+ Antagonizer(const sp<MediaPlayerBase::Listener> &listener);
void start() { mActive = true; }
void stop() { mActive = false; }
void kill();
@@ -57,12 +57,11 @@ private:
static const int interval;
Antagonizer();
static int callbackThread(void* cookie);
- Mutex mLock;
- Condition mCondition;
- bool mExit;
- bool mActive;
- void* mClient;
- notify_callback_f mCb;
+ Mutex mLock;
+ Condition mCondition;
+ bool mExit;
+ bool mActive;
+ sp<MediaPlayerBase::Listener> mListener;
};
#endif
@@ -205,7 +204,6 @@ class MediaPlayerService : public BnMediaPlayerService
}; // AudioOutput
-
public:
static void instantiate();
@@ -327,8 +325,7 @@ private:
void setDataSource_post(const sp<MediaPlayerBase>& p,
status_t status);
- static void notify(void* cookie, int msg,
- int ext1, int ext2, const Parcel *obj);
+ void notify(int msg, int ext1, int ext2, const Parcel *obj);
pid_t pid() const { return mPid; }
virtual status_t dump(int fd, const Vector<String16>& args);
@@ -370,23 +367,38 @@ private:
status_t setAudioAttributes_l(const Parcel &request);
- mutable Mutex mLock;
- sp<MediaPlayerBase> mPlayer;
- sp<MediaPlayerService> mService;
- sp<IMediaPlayerClient> mClient;
- sp<AudioOutput> mAudioOutput;
- pid_t mPid;
- status_t mStatus;
- bool mLoop;
- int32_t mConnId;
- int mAudioSessionId;
- audio_attributes_t * mAudioAttributes;
- uid_t mUID;
- sp<ANativeWindow> mConnectedWindow;
- sp<IBinder> mConnectedWindowBinder;
- struct sockaddr_in mRetransmitEndpoint;
- bool mRetransmitEndpointValid;
- sp<Client> mNextClient;
+ class Listener : public MediaPlayerBase::Listener {
+ public:
+ Listener(const wp<Client> &client) : mClient(client) {}
+ virtual ~Listener() {}
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
+ sp<Client> client = mClient.promote();
+ if (client != NULL) {
+ client->notify(msg, ext1, ext2, obj);
+ }
+ }
+ private:
+ wp<Client> mClient;
+ };
+
+ mutable Mutex mLock;
+ sp<MediaPlayerBase> mPlayer;
+ sp<MediaPlayerService> mService;
+ sp<IMediaPlayerClient> mClient;
+ sp<AudioOutput> mAudioOutput;
+ pid_t mPid;
+ status_t mStatus;
+ bool mLoop;
+ int32_t mConnId;
+ int mAudioSessionId;
+ audio_attributes_t * mAudioAttributes;
+ uid_t mUID;
+ sp<ANativeWindow> mConnectedWindow;
+ sp<IBinder> mConnectedWindowBinder;
+ struct sockaddr_in mRetransmitEndpoint;
+ bool mRetransmitEndpointValid;
+ sp<Client> mNextClient;
+ sp<MediaPlayerBase::Listener> mListener;
// Metadata filters.
media::Metadata::Filter mMetadataAllow; // protected by mLock
@@ -399,7 +411,7 @@ private:
media::Metadata::Filter mMetadataUpdated; // protected by mLock
#if CALLBACK_ANTAGONIZER
- Antagonizer* mAntagonizer;
+ Antagonizer* mAntagonizer;
#endif
}; // Client
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 2115eb4929..87538b589e 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -306,6 +306,10 @@ status_t AACSource::read(
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
if (mFrameDurationUs > 0) {
int64_t seekFrame = seekTimeUs / mFrameDurationUs;
+ if (seekFrame < 0 || seekFrame >= (int64_t)mOffsetVector.size()) {
+ android_errorWriteLog(0x534e4554, "70239507");
+ return ERROR_MALFORMED;
+ }
mCurrentTimeUs = seekFrame * mFrameDurationUs;
mOffset = mOffsetVector.itemAt(seekFrame);
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 9e37ed32c0..3ed2251bc7 100755
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1580,6 +1580,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
// ratio. Use compression ratio of 1.
max_size = width * height * 3 / 2;
}
+ // HACK: allow 10% overhead
+ // TODO: read sample size from traf atom for fragmented MPEG4.
+ max_size += max_size / 10;
mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size);
}
diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp
index c17faf32d8..b2d12f4da9 100644
--- a/media/libstagefright/VideoFrameScheduler.cpp
+++ b/media/libstagefright/VideoFrameScheduler.cpp
@@ -129,6 +129,11 @@ bool VideoFrameScheduler::PLL::fit(
numSamplesToUse = mNumSamples;
}
+ if ((period >> kPrecision) == 0 ) {
+ ALOGW("Period is 0, or after including precision is 0 - would cause div0, returning");
+ return false;
+ }
+
int64_t sumX = 0;
int64_t sumXX = 0;
int64_t sumXY = 0;
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index bf014ba6af..19556cc2cf 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -304,7 +304,7 @@ static sp<ABuffer> FindNAL(const uint8_t *data, size_t size, unsigned nalType) {
const uint8_t *nalStart;
size_t nalSize;
while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
- if ((nalStart[0] & 0x1f) == nalType) {
+ if (nalSize > 0 && (nalStart[0] & 0x1f) == nalType) {
sp<ABuffer> buffer = new ABuffer(nalSize);
memcpy(buffer->data(), nalStart, nalSize);
return buffer;
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 2130ccf856..2ca0e37b6a 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -317,10 +317,6 @@ status_t SoftAVC::initDecoder() {
status = ivdec_api_function(mCodecCtx, (void *)&s_create_ip, (void *)&s_create_op);
- mCodecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
- mCodecCtx->pv_fxns = dec_fxns;
- mCodecCtx->u4_size = sizeof(iv_obj_t);
-
if (status != IV_SUCCESS) {
ALOGE("Error in create: 0x%x",
s_create_op.s_ivd_create_op_t.u4_error_code);
@@ -328,6 +324,10 @@ status_t SoftAVC::initDecoder() {
mCodecCtx = NULL;
return UNKNOWN_ERROR;
}
+
+ mCodecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
+ mCodecCtx->pv_fxns = dec_fxns;
+ mCodecCtx->u4_size = sizeof(iv_obj_t);
}
/* Reset the plugin state */
@@ -545,7 +545,7 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
notifyEmptyBufferDone(inHeader);
if (!(inHeader->nFlags & OMX_BUFFERFLAG_EOS)) {
- continue;
+ return;
}
mReceivedEOS = true;
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 07d12453b0..8a8d84fe16 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -1134,6 +1134,12 @@ OMX_ERRORTYPE SoftAVC::setEncodeArgs(
ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
source = NULL;
if ((inputBufferHeader != NULL) && inputBufferHeader->nFilledLen) {
+ OMX_ERRORTYPE error = validateInputBuffer(inputBufferHeader);
+ if (error != OMX_ErrorNone) {
+ ALOGE("b/69065651");
+ android_errorWriteLog(0x534e4554, "69065651");
+ return error;
+ }
source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
if (mInputDataIsMeta) {
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index 1dac86804b..98fafbc9c3 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -278,10 +278,6 @@ status_t SoftHEVC::initDecoder() {
status = ivdec_api_function(mCodecCtx, (void *)&s_create_ip, (void *)&s_create_op);
- mCodecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
- mCodecCtx->pv_fxns = dec_fxns;
- mCodecCtx->u4_size = sizeof(iv_obj_t);
-
if (status != IV_SUCCESS) {
ALOGE("Error in create: 0x%x",
s_create_op.s_ivd_create_op_t.u4_error_code);
@@ -289,6 +285,10 @@ status_t SoftHEVC::initDecoder() {
mCodecCtx = NULL;
return UNKNOWN_ERROR;
}
+
+ mCodecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
+ mCodecCtx->pv_fxns = dec_fxns;
+ mCodecCtx->u4_size = sizeof(iv_obj_t);
}
/* Reset the plugin state */
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
index f7192b1c0f..7202f982eb 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
@@ -560,7 +560,7 @@ int PV_VlcDecMCBPC_com_inter_H263(BitstreamDecVideo *stream)
BitstreamShow13Bits(stream, &code);
- if (code == 0)
+ if (code < 8)
{
return VLC_CODE_ERROR;
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index 800238685e..fe98438a59 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -442,6 +442,14 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
}
if (inHeader->nFilledLen > 0) {
+ OMX_ERRORTYPE error = validateInputBuffer(inHeader);
+ if (error != OMX_ErrorNone) {
+ ALOGE("b/69065651");
+ android_errorWriteLog(0x534e4554, "69065651");
+ mSignalledError = true;
+ notify(OMX_EventError, error, 0, 0);
+ return;
+ }
const uint8_t *inputData = NULL;
if (mInputDataIsMeta) {
inputData =
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
index d443b7ccfe..bc5fd79526 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
@@ -184,7 +184,7 @@ ERROR_CODE pvmp3_decode_header(tmp3Bits *inputStream,
info->emphasis = (temp << 30) >> 30; /* 2 */
- if (!info->bitrate_index || info->sampling_frequency == 3)
+ if (!info->bitrate_index || info->bitrate_index == 15 || info->sampling_frequency == 3)
{
err = UNSUPPORTED_FREE_BITRATE;
}
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index 26c0fca559..fabe2e9654 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -726,6 +726,13 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
return;
}
+ OMX_ERRORTYPE error = validateInputBuffer(inputBufferHeader);
+ if (error != OMX_ErrorNone) {
+ ALOGE("b/27569635");
+ android_errorWriteLog(0x534e4554, "27569635");
+ notify(OMX_EventError, error, 0, 0);
+ return;
+ }
const uint8_t *source =
inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
@@ -741,14 +748,6 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
return;
}
} else {
- if (inputBufferHeader->nFilledLen < frameSize) {
- android_errorWriteLog(0x534e4554, "27569635");
- notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
- return;
- } else if (inputBufferHeader->nFilledLen > frameSize) {
- ALOGW("Input buffer contains too many pixels");
- }
-
if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
ConvertYUV420SemiPlanarToYUV420Planar(
source, mConversionBuffer, mWidth, mHeight);
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index ff2bb272ed..7b5e7d5920 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -655,10 +655,13 @@ status_t M3UParser::parse(const void *_data, size_t size) {
}
if (!line.startsWith("#")) {
+ if (itemMeta == NULL) {
+ ALOGV("itemMeta == NULL");
+ return ERROR_MALFORMED;
+ }
if (!mIsVariantPlaylist) {
int64_t durationUs;
- if (itemMeta == NULL
- || !itemMeta->findInt64("durationUs", &durationUs)) {
+ if (!itemMeta->findInt64("durationUs", &durationUs)) {
return ERROR_MALFORMED;
}
itemMeta->setInt32("discontinuity-sequence",
@@ -887,6 +890,9 @@ status_t M3UParser::parseStreamInf(
}
}
+ if (meta->get() == NULL) {
+ return ERROR_MALFORMED;
+ }
return OK;
}
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index fee13eac66..d97d444bd6 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -328,12 +328,25 @@ struct id3_header {
}
void ID3::removeUnsynchronization() {
- for (size_t i = 0; i + 1 < mSize; ++i) {
- if (mData[i] == 0xff && mData[i + 1] == 0x00) {
- memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2);
- --mSize;
+
+ // This file has "unsynchronization", so we have to replace occurrences
+ // of 0xff 0x00 with just 0xff in order to get the real data.
+
+ size_t writeOffset = 1;
+ for (size_t readOffset = 1; readOffset < mSize; ++readOffset) {
+ if (mData[readOffset - 1] == 0xff && mData[readOffset] == 0x00) {
+ continue;
}
+ // Only move data if there's actually something to move.
+ // This handles the special case of the data being only [0xff, 0x00]
+ // which should be converted to just 0xff if unsynchronization is on.
+ mData[writeOffset++] = mData[readOffset];
+ }
+
+ if (writeOffset < mSize) {
+ mSize = writeOffset;
}
+
}
static void WriteSyncsafeInteger(uint8_t *dst, size_t x) {
@@ -392,7 +405,12 @@ bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) {
--mSize;
--dataSize;
}
- mData[writeOffset++] = mData[readOffset++];
+ if (i + 1 < dataSize) {
+ // Only move data if there's actually something to move.
+ // This handles the special case of the data being only [0xff, 0x00]
+ // which should be converted to just 0xff if unsynchronization is on.
+ mData[writeOffset++] = mData[readOffset++];
+ }
}
// move the remaining data following this frame
if (readOffset <= oldSize) {
diff --git a/media/libstagefright/include/SoftVideoEncoderOMXComponent.h b/media/libstagefright/include/SoftVideoEncoderOMXComponent.h
index b43635deba..02555a2f34 100644
--- a/media/libstagefright/include/SoftVideoEncoderOMXComponent.h
+++ b/media/libstagefright/include/SoftVideoEncoderOMXComponent.h
@@ -68,6 +68,8 @@ protected:
virtual OMX_ERRORTYPE getExtensionIndex(const char *name, OMX_INDEXTYPE *index);
+ OMX_ERRORTYPE validateInputBuffer(const OMX_BUFFERHEADERTYPE *inputBufferHeader);
+
enum {
kInputPortIndex = 0,
kOutputPortIndex = 1,
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 7359e8bb1f..0542792278 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -1178,7 +1178,9 @@ static ssize_t getNextChunkSize(
const uint8_t *data, size_t size) {
static const char kStartCode[] = "\x00\x00\x01";
- if (size < 3) {
+ // per ISO/IEC 14496-2 6.2.1, a chunk has a 3-byte prefix + 1-byte start code
+ // we need at least <prefix><start><next prefix> to successfully scan
+ if (size < 3 + 1 + 3) {
return -EAGAIN;
}
@@ -1186,7 +1188,7 @@ static ssize_t getNextChunkSize(
return -EAGAIN;
}
- size_t offset = 3;
+ size_t offset = 4;
while (offset + 2 < size) {
if (!memcmp(&data[offset], kStartCode, 3)) {
return offset;
@@ -1237,6 +1239,9 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
state = EXPECT_VISUAL_OBJECT_START;
} else {
discard = true;
+ offset += chunkSize;
+ ALOGW("b/74114680, advance to next chunk");
+ android_errorWriteLog(0x534e4554, "74114680");
}
break;
}
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index d16d5df120..d2e6937151 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -36,6 +36,10 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
endif
endif
+ifeq ($(BOARD_SKIP_CVE_2017_13154),true)
+LOCAL_CFLAGS += -DSKIP_CVE_2017_13154
+endif
+
LOCAL_MODULE:= libstagefright_omx
LOCAL_CFLAGS += -Werror -Wall
LOCAL_CLANG := true
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 04d0b258aa..6f1ba9b6bb 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -378,6 +378,10 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {
break;
}
+#ifndef SKIP_CVE_2017_13154
+ Mutex::Autolock _l(mLock);
+#endif
+
ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName);
OMX_ERRORTYPE err = master->destroyComponentInstance(
static_cast<OMX_COMPONENTTYPE *>(mHandle));
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index dc3ed393fa..a8d54bcdb6 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -637,4 +637,17 @@ OMX_ERRORTYPE SoftVideoEncoderOMXComponent::getExtensionIndex(
return SimpleSoftOMXComponent::getExtensionIndex(name, index);
}
+OMX_ERRORTYPE SoftVideoEncoderOMXComponent::validateInputBuffer(
+ const OMX_BUFFERHEADERTYPE *inputBufferHeader) {
+ size_t frameSize = mInputDataIsMeta ?
+ max(sizeof(VideoNativeMetadata), sizeof(VideoGrallocMetadata))
+ : mWidth * mHeight * 3 / 2;
+ if (inputBufferHeader->nFilledLen < frameSize) {
+ return OMX_ErrorUndefined;
+ } else if (inputBufferHeader->nFilledLen > frameSize) {
+ ALOGW("Input buffer contains more data than expected.");
+ }
+ return OMX_ErrorNone;
+}
+
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 4e24f19daa..169a599033 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -827,6 +827,7 @@ AudioPortConfig::AudioPortConfig()
mSamplingRate = 0;
mChannelMask = AUDIO_CHANNEL_NONE;
mFormat = AUDIO_FORMAT_INVALID;
+ memset(&mGain, 0, sizeof(struct audio_gain_config));
mGain.index = -1;
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 45b3bb0972..7957af33bc 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -692,6 +692,7 @@ status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session
audio_io_handle_t *ioHandle,
audio_devices_t *device)
{
+ Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
@@ -701,6 +702,7 @@ status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session
status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session)
{
+ Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index a45d5f6ab8..4e54b919e7 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -528,6 +528,8 @@ void SoundTriggerHwService::Module::detach() {
if (!captureHotwordAllowed()) {
return;
}
+ Vector<audio_session_t> releasedSessions;
+
{
AutoMutex lock(mLock);
for (size_t i = 0; i < mModels.size(); i++) {
@@ -537,9 +539,16 @@ void SoundTriggerHwService::Module::detach() {
mHwDevice->stop_recognition(mHwDevice, model->mHandle);
}
mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
+ releasedSessions.add(model->mCaptureSession);
}
mModels.clear();
}
+
+ for (size_t i = 0; i < releasedSessions.size(); i++) {
+ // do not call AudioSystem methods with mLock held
+ AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
+ }
+
if (mClient != 0) {
IInterface::asBinder(mClient)->unlinkToDeath(this);
}
@@ -581,37 +590,43 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelM
return BAD_VALUE;
}
- AutoMutex lock(mLock);
-
- if (mModels.size() >= mDescriptor.properties.max_sound_models) {
- if (mModels.size() == 0) {
- return INVALID_OPERATION;
- }
- ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one",
- mDescriptor.properties.max_sound_models);
- unloadSoundModel_l(mModels.valueAt(0)->mHandle);
- }
-
- status_t status = mHwDevice->load_sound_model(mHwDevice,
- sound_model,
- SoundTriggerHwService::soundModelCallback,
- this,
- handle);
- if (status != NO_ERROR) {
- return status;
- }
audio_session_t session;
audio_io_handle_t ioHandle;
audio_devices_t device;
-
- status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
+ // do not call AudioSystem methods with mLock held
+ status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
if (status != NO_ERROR) {
return status;
}
- sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
- mModels.replaceValueFor(*handle, model);
+ {
+ AutoMutex lock(mLock);
+
+ if (mModels.size() >= mDescriptor.properties.max_sound_models) {
+ ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
+ mDescriptor.properties.max_sound_models);
+ status = INVALID_OPERATION;
+ goto exit;
+ }
+ status_t status = mHwDevice->load_sound_model(mHwDevice,
+ sound_model,
+ SoundTriggerHwService::soundModelCallback,
+ this,
+ handle);
+ if (status != NO_ERROR) {
+ goto exit;
+ }
+
+ sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
+ mModels.replaceValueFor(*handle, model);
+ }
+
+exit:
+ if (status != NO_ERROR) {
+ // do not call AudioSystem methods with mLock held
+ AudioSystem::releaseSoundTriggerSession(session);
+ }
return status;
}
@@ -621,25 +636,26 @@ status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t ha
if (!captureHotwordAllowed()) {
return PERMISSION_DENIED;
}
+ status_t status;
+ audio_session_t session;
- AutoMutex lock(mLock);
- return unloadSoundModel_l(handle);
-}
-
-status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
-{
- ssize_t index = mModels.indexOfKey(handle);
- if (index < 0) {
- return BAD_VALUE;
- }
- sp<Model> model = mModels.valueAt(index);
- mModels.removeItem(handle);
- if (model->mState == Model::STATE_ACTIVE) {
- mHwDevice->stop_recognition(mHwDevice, model->mHandle);
- model->mState = Model::STATE_IDLE;
- }
- AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
- return mHwDevice->unload_sound_model(mHwDevice, handle);
+ {
+ AutoMutex lock(mLock);
+ ssize_t index = mModels.indexOfKey(handle);
+ if (index < 0) {
+ return BAD_VALUE;
+ }
+ sp<Model> model = mModels.valueAt(index);
+ mModels.removeItem(handle);
+ if (model->mState == Model::STATE_ACTIVE) {
+ mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+ model->mState = Model::STATE_IDLE;
+ }
+ status = mHwDevice->unload_sound_model(mHwDevice, handle);
+ session = model->mCaptureSession;
+ }
+ AudioSystem::releaseSoundTriggerSession(session);
+ return status;
}
status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
index 2619a5fb49..d05dacdb7f 100644
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -141,9 +141,6 @@ public:
private:
- status_t unloadSoundModel_l(sound_model_handle_t handle);
-
-
Mutex mLock;
wp<SoundTriggerHwService> mService;
struct sound_trigger_hw_device* mHwDevice;