Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0ca0cea authored by Greg Kaiser's avatar Greg Kaiser Committed by Android (Google) Code Review
Browse files

Merge "Sensor: Make getId() more varied" into nyc-dev

parents ab69cc1f 53ca2e00
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -89,7 +89,14 @@ public:
    bool isDynamicSensor() const;
    bool hasAdditionalInfo() const;
    int32_t getReportingMode() const;

    // Note that after setId() has been called, getUuid() no longer
    // returns the UUID.
    // TODO(b/29547335): Remove getUuid(), add getUuidIndex(), and
    //     make sure setId() doesn't change the UuidIndex.
    const uuid_t& getUuid() const;
    int32_t getId() const;
    void setId(int32_t id);

    // LightFlattenable protocol
    inline bool isFixedSize() const { return false; }
@@ -116,6 +123,9 @@ private:
    int32_t mRequiredAppOp;
    int32_t mMaxDelay;
    uint32_t mFlags;
    // TODO(b/29547335): Get rid of this field and replace with an index.
    //     The index will be into a separate global vector of UUIDs.
    //     Also add an mId field (and change flatten/unflatten appropriately).
    uuid_t  mUuid;
    static void flattenString8(void*& buffer, size_t& size, const String8& string8);
    static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8);
+21 −1
Original line number Diff line number Diff line
@@ -408,6 +408,15 @@ const Sensor::uuid_t& Sensor::getUuid() const {
    return mUuid;
}

void Sensor::setId(int32_t id) {
    mUuid.i64[0] = id;
    mUuid.i64[1] = 0;
}

int32_t Sensor::getId() const {
    return int32_t(mUuid.i64[0]);
}

size_t Sensor::getFlattenedSize() const {
    size_t fixedSize =
            sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) +
@@ -448,7 +457,18 @@ status_t Sensor::flatten(void* buffer, size_t size) const {
    FlattenableUtils::write(buffer, size, mRequiredAppOp);
    FlattenableUtils::write(buffer, size, mMaxDelay);
    FlattenableUtils::write(buffer, size, mFlags);
    if (mUuid.i64[1] != 0) {
        // We should never hit this case with our current API, but we
        // could via a careless API change.  If that happens,
        // this code will keep us from leaking our UUID (while probably
        // breaking dynamic sensors).  See b/29547335.
        ALOGW("Sensor with UUID being flattened; sending 0.  Expect "
              "bad dynamic sensor behavior");
        uuid_t tmpUuid;  // default constructor makes this 0.
        FlattenableUtils::write(buffer, size, tmpUuid);
    } else {
        FlattenableUtils::write(buffer, size, mUuid);
    }
    return NO_ERROR;
}

+2 −1
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ LOCAL_SHARED_LIBRARIES := \
    liblog \
    libbinder \
    libui \
    libgui
    libgui \
    libcrypto

LOCAL_MODULE:= libsensorservice

+133 −1
Original line number Diff line number Diff line
@@ -26,6 +26,10 @@
#include <hardware/sensors.h>
#include <hardware_legacy/power.h>

#include <openssl/digest.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>

#include "BatteryService.h"
#include "CorrectedGyroSensor.h"
#include "GravitySensor.h"
@@ -44,8 +48,10 @@
#include <inttypes.h>
#include <math.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

namespace android {
// ---------------------------------------------------------------------------
@@ -60,6 +66,12 @@ namespace android {
 */

const char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock";
uint8_t SensorService::sHmacGlobalKey[128] = {};
bool SensorService::sHmacGlobalKeyIsValid = false;

#define SENSOR_SERVICE_DIR "/data/system/sensor_service"
#define SENSOR_SERVICE_HMAC_KEY_FILE  SENSOR_SERVICE_DIR "/hmac_key"

// Permissions.
static const String16 sDump("android.permission.DUMP");

@@ -68,10 +80,49 @@ SensorService::SensorService()
      mWakeLockAcquired(false) {
}

bool SensorService::initializeHmacKey() {
    int fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_RDONLY|O_CLOEXEC);
    if (fd != -1) {
        int result = read(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey));
        close(fd);
        if (result == sizeof(sHmacGlobalKey)) {
            return true;
        }
        ALOGW("Unable to read HMAC key; generating new one.");
    }

    if (RAND_bytes(sHmacGlobalKey, sizeof(sHmacGlobalKey)) == -1) {
        ALOGW("Can't generate HMAC key; dynamic sensor getId() will be wrong.");
        return false;
    }

    // We need to make sure this is only readable to us.
    bool wroteKey = false;
    mkdir(SENSOR_SERVICE_DIR, S_IRWXU);
    fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC,
              S_IRUSR|S_IWUSR);
    if (fd != -1) {
        int result = write(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey));
        close(fd);
        wroteKey = (result == sizeof(sHmacGlobalKey));
    }
    if (wroteKey) {
        ALOGI("Generated new HMAC key.");
    } else {
        ALOGW("Unable to write HMAC key; dynamic sensor getId() will change "
              "after reboot.");
    }
    // Even if we failed to write the key we return true, because we did
    // initialize the HMAC key.
    return true;
}

void SensorService::onFirstRef() {
    ALOGD("nuSensorService starting...");
    SensorDevice& dev(SensorDevice::getInstance());

    sHmacGlobalKeyIsValid = initializeHmacKey();

    if (dev.initCheck() == NO_ERROR) {
        sensor_t const* list;
        ssize_t count = dev.getSensorList(&list);
@@ -719,6 +770,85 @@ bool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
    return sensor != nullptr && sensor->getSensor().isWakeUpSensor();
}

int32_t SensorService::getIdFromUuid(const Sensor::uuid_t &uuid) const {
    if ((uuid.i64[0] == 0) && (uuid.i64[1] == 0)) {
        // UUID is not supported for this device.
        return 0;
    }
    if ((uuid.i64[0] == INT64_C(~0)) && (uuid.i64[1] == INT64_C(~0))) {
        // This sensor can be uniquely identified in the system by
        // the combination of its type and name.
        return -1;
    }

    // We have a dynamic sensor.

    if (!sHmacGlobalKeyIsValid) {
        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
        ALOGW("HMAC key failure; dynamic sensor getId() will be wrong.");
        return 0;
    }

    // We want each app author/publisher to get a different ID, so that the
    // same dynamic sensor cannot be tracked across apps by multiple
    // authors/publishers.  So we use both our UUID and our User ID.
    // Note potential confusion:
    //     UUID => Universally Unique Identifier.
    //     UID  => User Identifier.
    // We refrain from using "uid" except as needed by API to try to
    // keep this distinction clear.

    auto appUserId = IPCThreadState::self()->getCallingUid();
    uint8_t uuidAndApp[sizeof(uuid) + sizeof(appUserId)];
    memcpy(uuidAndApp, &uuid, sizeof(uuid));
    memcpy(uuidAndApp + sizeof(uuid), &appUserId, sizeof(appUserId));

    // Now we use our key on our UUID/app combo to get the hash.
    uint8_t hash[EVP_MAX_MD_SIZE];
    unsigned int hashLen;
    if (HMAC(EVP_sha256(),
             sHmacGlobalKey, sizeof(sHmacGlobalKey),
             uuidAndApp, sizeof(uuidAndApp),
             hash, &hashLen) == nullptr) {
        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
        ALOGW("HMAC failure; dynamic sensor getId() will be wrong.");
        return 0;
    }

    int32_t id = 0;
    if (hashLen < sizeof(id)) {
        // We never expect this case, but out of paranoia, we handle it.
        // Our 'id' length is already quite small, we don't want the
        // effective length of it to be even smaller.
        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
        ALOGW("HMAC insufficient; dynamic sensor getId() will be wrong.");
        return 0;
    }

    // This is almost certainly less than all of 'hash', but it's as secure
    // as we can be with our current 'id' length.
    memcpy(&id, hash, sizeof(id));

    // Note at the beginning of the function that we return the values of
    // 0 and -1 to represent special cases.  As a result, we can't return
    // those as dynamic sensor IDs.  If we happened to hash to one of those
    // values, we change 'id' so we report as a dynamic sensor, and not as
    // one of those special cases.
    if (id == -1) {
        id = -2;
    } else if (id == 0) {
        id = 1;
    }
    return id;
}

void SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const {
    for (auto &sensor : sensorList) {
        int32_t id = getIdFromUuid(sensor.getUuid());
        sensor.setId(id);
    }
}

Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.sensors", value, "0");
@@ -736,6 +866,7 @@ Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
                  sensor.getRequiredAppOp());
        }
    }
    makeUuidsIntoIdsForSensorList(accessibleSensorList);
    return accessibleSensorList;
}

@@ -755,6 +886,7 @@ Vector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName
                }
                return true;
            });
    makeUuidsIntoIdsForSensorList(accessibleSensorList);
    return accessibleSensorList;
}

+11 −0
Original line number Diff line number Diff line
@@ -208,6 +208,17 @@ private:
    status_t resetToNormalMode();
    status_t resetToNormalModeLocked();

    // Transforms the UUIDs for all the sensors into proper IDs.
    void makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const;
    // Gets the appropriate ID from the given UUID.
    int32_t getIdFromUuid(const Sensor::uuid_t &uuid) const;
    // Either read from storage or create a new one.
    static bool initializeHmacKey();


    static uint8_t sHmacGlobalKey[128];
    static bool sHmacGlobalKeyIsValid;

    SensorList mSensors;
    status_t mInitCheck;