From 1e9c510d4960269486aa6df9ef9ac53f8fff50f3 Mon Sep 17 00:00:00 2001 From: Andrew Lehmer Date: Mon, 30 Mar 2020 14:12:15 -0700 Subject: [PATCH] folio_daemon: Avoid UAF with stale sensor handle It is possible for sensor handles retrieved using ASensorManager_getDefaultSensor() to become stale if the underlying binder connection to the sensor service gets reset. This can be triggered by ASensorManager_createEventQueue(), so any sensor handle retrieved prior to this call may become stale, resulting in a use-after- free when the handle is eventually registered with the queue. To avoid this, the event queue is created before retrieving or registering the sensor. Bug: 150225255 Test: No longer crashes with proof-of-concept on Pixel 2 XL. Change-Id: I243f6c68c734af3eb5488855d965a894b5fb99e5 --- folio_daemon/main.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/folio_daemon/main.cpp b/folio_daemon/main.cpp index 992b4a59..b3a9aa13 100644 --- a/folio_daemon/main.cpp +++ b/folio_daemon/main.cpp @@ -43,6 +43,7 @@ int main(void) { ASensorRef hallSensor; ALooper *looper; ASensorEventQueue *eventQueue = nullptr; + int32_t hallMinDelay = 0; time_t lastWarn = 0; int attemptCount = 0; @@ -85,6 +86,14 @@ int main(void) { // Get Hall-effect sensor events from the NDK sensorManager = ASensorManager_getInstanceForPackage(nullptr); + looper = ALooper_forThread(); + if (looper == nullptr) { + looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); + } + + eventQueue = ASensorManager_createEventQueue(sensorManager, looper, 0, NULL, + NULL); + /* * As long as we are unable to get the sensor handle, periodically retry * and emit an error message at a low frequency to prevent high CPU usage @@ -96,6 +105,7 @@ int main(void) { hallSensor = ASensorManager_getDefaultSensor(sensorManager, SENSOR_TYPE); if (hallSensor != nullptr) { + hallMinDelay = ASensor_getMinDelay(hallSensor); break; } @@ -110,16 +120,8 @@ int main(void) { sleep(RETRY_PERIOD); } - looper = ALooper_forThread(); - if (looper == nullptr) { - looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); - } - - eventQueue = ASensorManager_createEventQueue(sensorManager, looper, 0, NULL, - NULL); err = ASensorEventQueue_registerSensor(eventQueue, hallSensor, - ASensor_getMinDelay(hallSensor), - 10000); + hallMinDelay, 10000); if (err < 0) { ALOGE("Unable to register for Hall-effect sensor events"); goto out;