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
diff --git a/folio_daemon/main.cpp b/folio_daemon/main.cpp
index 1cda1ce..6bc7027 100644
--- a/folio_daemon/main.cpp
+++ b/folio_daemon/main.cpp
@@ -45,6 +45,7 @@
ASensorRef hallSensor;
ALooper *looper;
ASensorEventQueue *eventQueue = nullptr;
+ int32_t hallMinDelay = 0;
time_t lastWarn = 0;
int attemptCount = 0;
@@ -87,6 +88,14 @@
// 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
@@ -98,6 +107,7 @@
hallSensor = ASensorManager_getDefaultSensor(sensorManager,
SENSOR_TYPE);
if (hallSensor != nullptr) {
+ hallMinDelay = ASensor_getMinDelay(hallSensor);
break;
}
@@ -112,16 +122,8 @@
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;