merge in nyc-release history after reset to nyc-dev
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index b9c9e75..5fe1f90 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -625,6 +625,15 @@
return true;
}
+static void dump_iptables() {
+ run_command("IPTABLES", 10, "iptables", "-L", "-nvx", NULL);
+ run_command("IP6TABLES", 10, "ip6tables", "-L", "-nvx", NULL);
+ run_command("IPTABLE NAT", 10, "iptables", "-t", "nat", "-L", "-nvx", NULL);
+ /* no ip6 nat */
+ run_command("IPTABLE RAW", 10, "iptables", "-t", "raw", "-L", "-nvx", NULL);
+ run_command("IP6TABLE RAW", 10, "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
+}
+
static void dumpstate(const std::string& screenshot_path, const std::string& version) {
DurationReporter duration_reporter("DUMPSTATE");
unsigned long timeout;
@@ -798,16 +807,7 @@
run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL);
run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL);
run_command("MULTICAST ADDRESSES", 10, "ip", "maddr", NULL);
-
- run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
- run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
- run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
- /* no ip6 nat */
- run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL);
- run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
-
- run_command("WIFI NETWORKS", 20,
- SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL);
+ run_command("WIFI NETWORKS", 20, "wpa_cli", "IFNAME=wlan0", "list_networks", NULL);
#ifdef FWDUMP_bcmdhd
run_command("ND OFFLOAD TABLE", 5,
@@ -1281,12 +1281,13 @@
/* collect stack traces from Dalvik and native processes (needs root) */
dump_traces_path = dump_traces();
- /* Get the tombstone fds, recovery files, and mount info here while we are running as root. */
+ /* Run some operations that require root. */
get_tombstone_fds(tombstone_data);
add_dir(RECOVERY_DIR, true);
add_dir(RECOVERY_DATA_DIR, true);
add_dir(LOGPERSIST_DATA_DIR, false);
add_mountinfo();
+ dump_iptables();
if (!drop_root_user()) {
return -1;
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 3f60741..094fd16 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -89,7 +89,14 @@
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 @@
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);
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index cc865d1..053d153 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -408,6 +408,15 @@
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 @@
FlattenableUtils::write(buffer, size, mRequiredAppOp);
FlattenableUtils::write(buffer, size, mMaxDelay);
FlattenableUtils::write(buffer, size, mFlags);
- FlattenableUtils::write(buffer, size, mUuid);
+ 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;
}
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index 5a36961..7b10319 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -34,7 +34,8 @@
liblog \
libbinder \
libui \
- libgui
+ libgui \
+ libcrypto
LOCAL_MODULE:= libsensorservice
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 6caa85b..fb83eff 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -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 @@
*/
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 @@
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 @@
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 @@
sensor.getRequiredAppOp());
}
}
+ makeUuidsIntoIdsForSensorList(accessibleSensorList);
return accessibleSensorList;
}
@@ -755,6 +886,7 @@
}
return true;
});
+ makeUuidsIntoIdsForSensorList(accessibleSensorList);
return accessibleSensorList;
}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 0d04478..c8de621 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -208,6 +208,17 @@
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;