aaudio: use weak pointer to prevent UAF
Avoid using the mServiceEndpoint smart pointer
from multiple threads.
Bug: 74122779
Test: see bug for test instructions
Change-Id: Idaf9e32a163b25e51bde35d6f5ea10a372b5d916
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 864a008..05c5735 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -128,6 +128,12 @@
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ result = AAUDIO_ERROR_INVALID_STATE;
+ goto error;
+ }
+
// Is the request compatible with the shared endpoint?
setFormat(configurationInput.getFormat());
if (getFormat() == AAUDIO_FORMAT_UNSPECIFIED) {
@@ -140,20 +146,20 @@
setSampleRate(configurationInput.getSampleRate());
if (getSampleRate() == AAUDIO_UNSPECIFIED) {
- setSampleRate(mServiceEndpoint->getSampleRate());
- } else if (getSampleRate() != mServiceEndpoint->getSampleRate()) {
+ setSampleRate(endpoint->getSampleRate());
+ } else if (getSampleRate() != endpoint->getSampleRate()) {
ALOGD("%s() mSampleRate = %d, need %d",
- __func__, getSampleRate(), mServiceEndpoint->getSampleRate());
+ __func__, getSampleRate(), endpoint->getSampleRate());
result = AAUDIO_ERROR_INVALID_RATE;
goto error;
}
setSamplesPerFrame(configurationInput.getSamplesPerFrame());
if (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) {
- setSamplesPerFrame(mServiceEndpoint->getSamplesPerFrame());
- } else if (getSamplesPerFrame() != mServiceEndpoint->getSamplesPerFrame()) {
+ setSamplesPerFrame(endpoint->getSamplesPerFrame());
+ } else if (getSamplesPerFrame() != endpoint->getSamplesPerFrame()) {
ALOGD("%s() mSamplesPerFrame = %d, need %d",
- __func__, getSamplesPerFrame(), mServiceEndpoint->getSamplesPerFrame());
+ __func__, getSamplesPerFrame(), endpoint->getSamplesPerFrame());
result = AAUDIO_ERROR_OUT_OF_RANGE;
goto error;
}
@@ -179,7 +185,10 @@
}
}
- result = mServiceEndpoint->registerStream(keep);
+ ALOGD("AAudioServiceStreamShared::open() actual rate = %d, channels = %d, deviceId = %d",
+ getSampleRate(), getSamplesPerFrame(), endpoint->getDeviceId());
+
+ result = endpoint->registerStream(keep);
if (result != AAUDIO_OK) {
goto error;
}
@@ -246,7 +255,13 @@
int64_t *timeNanos) {
int64_t position = 0;
- aaudio_result_t result = mServiceEndpoint->getTimestamp(&position, timeNanos);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+
+ aaudio_result_t result = endpoint->getTimestamp(&position, timeNanos);
if (result == AAUDIO_OK) {
int64_t offset = mTimestampPositionOffset.load();
// TODO, do not go below starting value