Skip to content

Commit

Permalink
Fix security vulnerability: potential OOB write in audioserver
Browse files Browse the repository at this point in the history
Bug: 32705438
Bug: 32703959
Test: cts security test
Change-Id: I8900c92fa55b56c4c2c9d721efdbabe6bfc8a4a4
(cherry picked from commit e275907)
(cherry picked from commit b0bcddb44d992e74140a3f5eedc7177977ea8e34)
  • Loading branch information
rago authored and andi34 committed Mar 17, 2017
1 parent cf6aea2 commit b317df8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
27 changes: 21 additions & 6 deletions media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
Expand Up @@ -2829,24 +2829,39 @@ int Effect_command(effect_handle_t self,
//ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM start"); //ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM start");


effect_param_t *p = (effect_param_t *)pCmdData; effect_param_t *p = (effect_param_t *)pCmdData;
if (SIZE_MAX - sizeof(effect_param_t) < (size_t)p->psize) {
android_errorWriteLog(0x534e4554, "26347509");
return -EINVAL;
}
if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) || if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
cmdSize < (sizeof(effect_param_t) + p->psize) || cmdSize < (sizeof(effect_param_t) + p->psize) ||
pReplyData == NULL || replySize == NULL || pReplyData == NULL || replySize == NULL ||
*replySize < (sizeof(effect_param_t) + p->psize)) { *replySize < (sizeof(effect_param_t) + p->psize)) {
ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: ERROR"); ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: ERROR");
return -EINVAL; return -EINVAL;
} }
if (EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) < (size_t)p->psize) {
android_errorWriteLog(0x534e4554, "26347509");
ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: psize too big");
return -EINVAL;
}
uint32_t paddedParamSize = ((p->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) *
sizeof(int32_t);
if ((EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) < paddedParamSize) ||
(EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) - paddedParamSize <
p->vsize)) {
ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: padded_psize or vsize too big");
return -EINVAL;
}
uint32_t expectedReplySize = sizeof(effect_param_t) + paddedParamSize + p->vsize;
if (*replySize < expectedReplySize) {
ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: min. replySize %u, got %u bytes",
expectedReplySize, *replySize);
android_errorWriteLog(0x534e4554, "32705438");
return -EINVAL;
}


memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize); memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);


p = (effect_param_t *)pReplyData; p = (effect_param_t *)pReplyData;


int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); uint32_t voffset = paddedParamSize;

if(pContext->EffectType == LVM_BASS_BOOST){ if(pContext->EffectType == LVM_BASS_BOOST){
p->status = android::BassBoost_getParameter(pContext, p->status = android::BassBoost_getParameter(pContext,
p->data, p->data,
Expand Down
12 changes: 12 additions & 0 deletions media/libmedia/IEffect.cpp
Expand Up @@ -25,6 +25,9 @@


namespace android { namespace android {


// Maximum command/reply size expected
#define EFFECT_PARAM_SIZE_MAX 65536

enum { enum {
ENABLE = IBinder::FIRST_CALL_TRANSACTION, ENABLE = IBinder::FIRST_CALL_TRANSACTION,
DISABLE, DISABLE,
Expand Down Expand Up @@ -153,6 +156,10 @@ status_t BnEffect::onTransact(
uint32_t cmdSize = data.readInt32(); uint32_t cmdSize = data.readInt32();
char *cmd = NULL; char *cmd = NULL;
if (cmdSize) { if (cmdSize) {
if (cmdSize > EFFECT_PARAM_SIZE_MAX) {
reply->writeInt32(NO_MEMORY);
return NO_ERROR;
}
cmd = (char *)calloc(cmdSize, 1); cmd = (char *)calloc(cmdSize, 1);
if (cmd == NULL) { if (cmd == NULL) {
reply->writeInt32(NO_MEMORY); reply->writeInt32(NO_MEMORY);
Expand All @@ -164,6 +171,11 @@ status_t BnEffect::onTransact(
uint32_t replySz = replySize; uint32_t replySz = replySize;
char *resp = NULL; char *resp = NULL;
if (replySize) { if (replySize) {
if (replySize > EFFECT_PARAM_SIZE_MAX) {
free(cmd);
reply->writeInt32(NO_MEMORY);
return NO_ERROR;
}
resp = (char *)calloc(replySize, 1); resp = (char *)calloc(replySize, 1);
if (resp == NULL) { if (resp == NULL) {
free(cmd); free(cmd);
Expand Down
16 changes: 16 additions & 0 deletions services/audioflinger/Effects.cpp
Expand Up @@ -546,6 +546,22 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
android_errorWriteLog(0x534e4554, "32438594"); android_errorWriteLog(0x534e4554, "32438594");
return -EINVAL; return -EINVAL;
} }
if (cmdCode == EFFECT_CMD_GET_PARAM &&
(sizeof(effect_param_t) > *replySize
|| ((effect_param_t *)pCmdData)->psize > *replySize
- sizeof(effect_param_t)
|| ((effect_param_t *)pCmdData)->vsize > *replySize
- sizeof(effect_param_t)
- ((effect_param_t *)pCmdData)->psize
|| roundUpDelta(((effect_param_t *)pCmdData)->psize, (uint32_t)sizeof(int)) >
*replySize
- sizeof(effect_param_t)
- ((effect_param_t *)pCmdData)->psize
- ((effect_param_t *)pCmdData)->vsize)) {
ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: reply size inconsistent");
android_errorWriteLog(0x534e4554, "32705438");
return -EINVAL;
}
if ((cmdCode == EFFECT_CMD_SET_PARAM if ((cmdCode == EFFECT_CMD_SET_PARAM
|| cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) && // DEFERRED not generally used || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) && // DEFERRED not generally used
(sizeof(effect_param_t) > cmdSize (sizeof(effect_param_t) > cmdSize
Expand Down

0 comments on commit b317df8

Please sign in to comment.