Use resolution to round sensor event values
Add method to utilize a sensor's specified resolution value to ensure
data isn't provided that is more fine-grained than expected. This
helps mitigate sensor calibration fingerprinting attacks.
Bug: 147725937
Test: Verify accel sensor data isn't more fine grained than its
specified resolution
Change-Id: I81905cde22cc8429021ffb8318a222512ce01900
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 3b68e0e..aa6f1b8 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -143,6 +143,14 @@
for (size_t i=0 ; i < count; i++) {
sensor_t sensor;
convertToSensor(convertToOldSensorInfo(list[i]), &sensor);
+
+ if (sensor.resolution == 0) {
+ // Don't crash here or the device will go into a crashloop.
+ ALOGE("%s must have a non-zero resolution", sensor.name);
+ // For simple algos, map their resolution to 1 if it's not specified
+ sensor.resolution = SensorDeviceUtils::defaultResolutionForType(sensor.type);
+ }
+
// Sanity check and clamp power if it is 0 (or close)
if (sensor.power < minPowerMa) {
ALOGI("Reported power %f not deemed sane, clamping to %f",
@@ -508,7 +516,7 @@
const auto &events,
const auto &dynamicSensorsAdded) {
if (result == Result::OK) {
- convertToSensorEvents(convertToNewEvents(events),
+ convertToSensorEventsAndQuantize(convertToNewEvents(events),
convertToNewSensorInfos(dynamicSensorsAdded), buffer);
err = (ssize_t)events.size();
} else {
@@ -571,6 +579,8 @@
for (size_t i = 0; i < eventsToRead; i++) {
convertToSensorEvent(mEventBuffer[i], &buffer[i]);
+ android::SensorDeviceUtils::quantizeSensorEventValues(&buffer[i],
+ getResolutionForSensor(buffer[i].sensor));
}
eventsRead = eventsToRead;
} else {
@@ -1077,7 +1087,7 @@
}
}
-void SensorDevice::convertToSensorEvents(
+void SensorDevice::convertToSensorEventsAndQuantize(
const hidl_vec<Event> &src,
const hidl_vec<SensorInfo> &dynamicSensorsAdded,
sensors_event_t *dst) {
@@ -1088,9 +1098,26 @@
for (size_t i = 0; i < src.size(); ++i) {
V2_1::implementation::convertToSensorEvent(src[i], &dst[i]);
+ android::SensorDeviceUtils::quantizeSensorEventValues(&dst[i],
+ getResolutionForSensor(dst[i].sensor));
}
}
+float SensorDevice::getResolutionForSensor(int sensorHandle) {
+ for (size_t i = 0; i < mSensorList.size(); i++) {
+ if (sensorHandle == mSensorList[i].handle) {
+ return mSensorList[i].resolution;
+ }
+ }
+
+ auto it = mConnectedDynamicSensors.find(sensorHandle);
+ if (it != mConnectedDynamicSensors.end()) {
+ return it->second->resolution;
+ }
+
+ return 0;
+}
+
void SensorDevice::handleHidlDeath(const std::string & detail) {
if (!mSensors->supportsMessageQueues()) {
// restart is the only option at present.