OSDN Git Service
(root)
/
android-x86
/
frameworks-av.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
aaudio: use weak pointer to prevent UAF
[android-x86/frameworks-av.git]
/
services
/
oboeservice
/
AAudioServiceStreamBase.cpp
diff --git
a/services/oboeservice/AAudioServiceStreamBase.cpp
b/services/oboeservice/AAudioServiceStreamBase.cpp
index
ff0b037
..
d9b8766
100644
(file)
--- a/
services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/
services/oboeservice/AAudioServiceStreamBase.cpp
@@
-104,6
+104,9
@@
aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest
goto error;
}
goto error;
}
+ // This is not protected by a lock because the stream cannot be
+ // referenced until the service returns a handle to the client.
+ // So only one thread can open a stream.
mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
request,
sharingMode);
mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
request,
sharingMode);
@@
-112,6
+115,9
@@
aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;
}
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;
}
+ // Save a weak pointer that we will use to access the endpoint.
+ mServiceEndpointWeak = mServiceEndpoint;
+
mFramesPerBurst = mServiceEndpoint->getFramesPerBurst();
copyFrom(*mServiceEndpoint);
}
mFramesPerBurst = mServiceEndpoint->getFramesPerBurst();
copyFrom(*mServiceEndpoint);
}
@@
-130,15
+136,19
@@
aaudio_result_t AAudioServiceStreamBase::close() {
stop();
stop();
- if (mServiceEndpoint == nullptr) {
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
result = AAUDIO_ERROR_INVALID_STATE;
} else {
result = AAUDIO_ERROR_INVALID_STATE;
} else {
- mServiceEndpoint->unregisterStream(this);
- AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
- mEndpointManager.closeEndpoint(mServiceEndpoint);
- mServiceEndpoint.clear();
+ endpoint->unregisterStream(this);
+ AAudioEndpointManager &endpointManager = AAudioEndpointManager::getInstance();
+ endpointManager.closeEndpoint(endpoint);
+
+ // AAudioService::closeStream() prevents two threads from closing at the same time.
+ mServiceEndpoint.clear(); // endpoint will hold the pointer until this method returns.
}
}
+
{
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
stopTimestampThread();
{
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
stopTimestampThread();
@@
-152,7
+162,12
@@
aaudio_result_t AAudioServiceStreamBase::close() {
aaudio_result_t AAudioServiceStreamBase::startDevice() {
mClientHandle = AUDIO_PORT_HANDLE_NONE;
aaudio_result_t AAudioServiceStreamBase::startDevice() {
mClientHandle = AUDIO_PORT_HANDLE_NONE;
- return mServiceEndpoint->startStream(this, &mClientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return endpoint->startStream(this, &mClientHandle);
}
/**
}
/**
@@
-162,16
+177,11
@@
aaudio_result_t AAudioServiceStreamBase::startDevice() {
*/
aaudio_result_t AAudioServiceStreamBase::start() {
aaudio_result_t result = AAUDIO_OK;
*/
aaudio_result_t AAudioServiceStreamBase::start() {
aaudio_result_t result = AAUDIO_OK;
+
if (isRunning()) {
return AAUDIO_OK;
}
if (isRunning()) {
return AAUDIO_OK;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamBase::start() missing endpoint");
- result = AAUDIO_ERROR_INVALID_STATE;
- goto error;
- }
-
// Start with fresh presentation timestamps.
mAtomicTimestamp.clear();
// Start with fresh presentation timestamps.
mAtomicTimestamp.clear();
@@
-198,10
+208,6
@@
aaudio_result_t AAudioServiceStreamBase::pause() {
if (!isRunning()) {
return result;
}
if (!isRunning()) {
return result;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamShared::pause() missing endpoint");
- return AAUDIO_ERROR_INVALID_STATE;
- }
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
@@
-213,7
+219,12
@@
aaudio_result_t AAudioServiceStreamBase::pause() {
return result;
}
return result;
}
- result = mServiceEndpoint->stopStream(this, mClientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ result = endpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
disconnect(); // TODO should we return or pause Base first?
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
disconnect(); // TODO should we return or pause Base first?
@@
-230,11
+241,6
@@
aaudio_result_t AAudioServiceStreamBase::stop() {
return result;
}
return result;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamShared::stop() missing endpoint");
- return AAUDIO_ERROR_INVALID_STATE;
- }
-
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
sendCurrentTimestamp(); // warning - this calls a virtual function
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
sendCurrentTimestamp(); // warning - this calls a virtual function
@@
-244,8
+250,13
@@
aaudio_result_t AAudioServiceStreamBase::stop() {
return result;
}
return result;
}
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
// TODO wait for data to be played out
// TODO wait for data to be played out
- result =
mServiceE
ndpoint->stopStream(this, mClientHandle);
+ result =
e
ndpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
disconnect();
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
disconnect();