Merge changes I42162365,Ia72f1305,I57d1f86c,I026d074e
* changes:
logd: klogd deal with nuls in dmesg
logd: log_strtok_r deal with nuls
liblog: logprint: printable nul
logd: klogd: sniff for time correction on Mediatek
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index a4a99c3..eddc3e4 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -47,6 +47,8 @@
#define VERITY_METADATA_SIZE 32768
#define VERITY_TABLE_RSA_KEY "/verity_key"
+#define VERITY_TABLE_HASH_IDX 8
+#define VERITY_TABLE_SALT_IDX 9
#define METADATA_MAGIC 0x01564c54
#define METADATA_TAG_MAX_LENGTH 63
@@ -141,6 +143,33 @@
return retval;
}
+static int invalidate_table(char *table, int table_length)
+{
+ int n = 0;
+ int idx = 0;
+ int cleared = 0;
+
+ while (n < table_length) {
+ if (table[n++] == ' ') {
+ ++idx;
+ }
+
+ if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) {
+ continue;
+ }
+
+ while (n < table_length && table[n] != ' ') {
+ table[n++] = '0';
+ }
+
+ if (++cleared == 2) {
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
static int squashfs_get_target_device_size(char *blk_device, uint64_t *device_size)
{
struct squashfs_info sq_info;
@@ -957,6 +986,7 @@
char *verity_blk_name = 0;
char *verity_table = 0;
char *verity_table_signature = 0;
+ int verity_table_length = 0;
uint64_t device_size = 0;
_Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE];
@@ -979,6 +1009,7 @@
}
retval = FS_MGR_SETUP_VERITY_FAIL;
+ verity_table_length = strlen(verity_table);
// get the device mapper fd
if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
@@ -998,13 +1029,6 @@
goto out;
}
- // verify the signature on the table
- if (verify_table(verity_table_signature,
- verity_table,
- strlen(verity_table)) < 0) {
- goto out;
- }
-
if (load_verity_state(fstab, &mode) < 0) {
/* if accessing or updating the state failed, switch to the default
* safe mode. This makes sure the device won't end up in an endless
@@ -1013,6 +1037,22 @@
mode = VERITY_MODE_EIO;
}
+ // verify the signature on the table
+ if (verify_table(verity_table_signature,
+ verity_table,
+ verity_table_length) < 0) {
+ if (mode == VERITY_MODE_LOGGING) {
+ // the user has been warned, allow mounting without dm-verity
+ retval = FS_MGR_SETUP_VERITY_SUCCESS;
+ goto out;
+ }
+
+ // invalidate root hash and salt to trigger device-specific recovery
+ if (invalidate_table(verity_table, verity_table_length) < 0) {
+ goto out;
+ }
+ }
+
INFO("Enabling dm-verity for %s (mode %d)\n", mount_point, mode);
// load the verity mapping table
diff --git a/include/utils/LruCache.h b/include/utils/LruCache.h
index cd9d7f9..7818b4e 100644
--- a/include/utils/LruCache.h
+++ b/include/utils/LruCache.h
@@ -17,8 +17,11 @@
#ifndef ANDROID_UTILS_LRU_CACHE_H
#define ANDROID_UTILS_LRU_CACHE_H
+#include <unordered_set>
+
#include <UniquePtr.h>
-#include <utils/BasicHashtable.h>
+
+#include "utils/TypeHelpers.h" // hash_t
namespace android {
@@ -36,6 +39,7 @@
class LruCache {
public:
explicit LruCache(uint32_t maxCapacity);
+ virtual ~LruCache();
enum Capacity {
kUnlimitedCapacity,
@@ -50,32 +54,6 @@
void clear();
const TValue& peekOldestValue();
- class Iterator {
- public:
- Iterator(const LruCache<TKey, TValue>& cache): mCache(cache), mIndex(-1) {
- }
-
- bool next() {
- mIndex = mCache.mTable->next(mIndex);
- return (ssize_t)mIndex != -1;
- }
-
- size_t index() const {
- return mIndex;
- }
-
- const TValue& value() const {
- return mCache.mTable->entryAt(mIndex).value;
- }
-
- const TKey& key() const {
- return mCache.mTable->entryAt(mIndex).key;
- }
- private:
- const LruCache<TKey, TValue>& mCache;
- size_t mIndex;
- };
-
private:
LruCache(const LruCache& that); // disallow copy constructor
@@ -90,27 +68,79 @@
const TKey& getKey() const { return key; }
};
+ struct HashForEntry : public std::unary_function<Entry*, hash_t> {
+ size_t operator() (const Entry* entry) const {
+ return hash_type(entry->key);
+ };
+ };
+
+ struct EqualityForHashedEntries : public std::unary_function<Entry*, hash_t> {
+ bool operator() (const Entry* lhs, const Entry* rhs) const {
+ return lhs->key == rhs->key;
+ };
+ };
+
+ typedef std::unordered_set<Entry*, HashForEntry, EqualityForHashedEntries> LruCacheSet;
+
void attachToCache(Entry& entry);
void detachFromCache(Entry& entry);
- void rehash(size_t newCapacity);
- UniquePtr<BasicHashtable<TKey, Entry> > mTable;
+ typename LruCacheSet::iterator findByKey(const TKey& key) {
+ Entry entryForSearch(key, mNullValue);
+ typename LruCacheSet::iterator result = mSet->find(&entryForSearch);
+ return result;
+ }
+
+ UniquePtr<LruCacheSet> mSet;
OnEntryRemoved<TKey, TValue>* mListener;
Entry* mOldest;
Entry* mYoungest;
uint32_t mMaxCapacity;
TValue mNullValue;
+
+public:
+ class Iterator {
+ public:
+ Iterator(const LruCache<TKey, TValue>& cache): mCache(cache), mIterator(mCache.mSet->begin()) {
+ }
+
+ bool next() {
+ if (mIterator == mCache.mSet->end()) {
+ return false;
+ }
+ std::advance(mIterator, 1);
+ return mIterator != mCache.mSet->end();
+ }
+
+ const TValue& value() const {
+ return (*mIterator)->value;
+ }
+
+ const TKey& key() const {
+ return (*mIterator)->key;
+ }
+ private:
+ const LruCache<TKey, TValue>& mCache;
+ typename LruCacheSet::iterator mIterator;
+ };
};
// Implementation is here, because it's fully templated
template <typename TKey, typename TValue>
LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity)
- : mTable(new BasicHashtable<TKey, Entry>)
+ : mSet(new LruCacheSet())
, mListener(NULL)
, mOldest(NULL)
, mYoungest(NULL)
, mMaxCapacity(maxCapacity)
, mNullValue(NULL) {
+ mSet->max_load_factor(1.0);
+};
+
+template <typename TKey, typename TValue>
+LruCache<TKey, TValue>::~LruCache() {
+ // Need to delete created entries.
+ clear();
};
template<typename K, typename V>
@@ -120,20 +150,19 @@
template <typename TKey, typename TValue>
size_t LruCache<TKey, TValue>::size() const {
- return mTable->size();
+ return mSet->size();
}
template <typename TKey, typename TValue>
const TValue& LruCache<TKey, TValue>::get(const TKey& key) {
- hash_t hash = hash_type(key);
- ssize_t index = mTable->find(-1, hash, key);
- if (index == -1) {
+ typename LruCacheSet::const_iterator find_result = findByKey(key);
+ if (find_result == mSet->end()) {
return mNullValue;
}
- Entry& entry = mTable->editEntryAt(index);
- detachFromCache(entry);
- attachToCache(entry);
- return entry.value;
+ Entry *entry = *find_result;
+ detachFromCache(*entry);
+ attachToCache(*entry);
+ return entry->value;
}
template <typename TKey, typename TValue>
@@ -142,36 +171,29 @@
removeOldest();
}
- hash_t hash = hash_type(key);
- ssize_t index = mTable->find(-1, hash, key);
- if (index >= 0) {
+ if (findByKey(key) != mSet->end()) {
return false;
}
- if (!mTable->hasMoreRoom()) {
- rehash(mTable->capacity() * 2);
- }
- // Would it be better to initialize a blank entry and assign key, value?
- Entry initEntry(key, value);
- index = mTable->add(hash, initEntry);
- Entry& entry = mTable->editEntryAt(index);
- attachToCache(entry);
+ Entry* newEntry = new Entry(key, value);
+ mSet->insert(newEntry);
+ attachToCache(*newEntry);
return true;
}
template <typename TKey, typename TValue>
bool LruCache<TKey, TValue>::remove(const TKey& key) {
- hash_t hash = hash_type(key);
- ssize_t index = mTable->find(-1, hash, key);
- if (index < 0) {
+ typename LruCacheSet::const_iterator find_result = findByKey(key);
+ if (find_result == mSet->end()) {
return false;
}
- Entry& entry = mTable->editEntryAt(index);
+ Entry* entry = *find_result;
if (mListener) {
- (*mListener)(entry.key, entry.value);
+ (*mListener)(entry->key, entry->value);
}
- detachFromCache(entry);
- mTable->removeAt(index);
+ detachFromCache(*entry);
+ mSet->erase(entry);
+ delete entry;
return true;
}
@@ -201,7 +223,10 @@
}
mYoungest = NULL;
mOldest = NULL;
- mTable->clear();
+ for (auto entry : *mSet.get()) {
+ delete entry;
+ }
+ mSet->clear();
}
template <typename TKey, typename TValue>
@@ -232,19 +257,5 @@
entry.child = NULL;
}
-template <typename TKey, typename TValue>
-void LruCache<TKey, TValue>::rehash(size_t newCapacity) {
- UniquePtr<BasicHashtable<TKey, Entry> > oldTable(mTable.release());
- Entry* oldest = mOldest;
-
- mOldest = NULL;
- mYoungest = NULL;
- mTable.reset(new BasicHashtable<TKey, Entry>(newCapacity));
- for (Entry* p = oldest; p != NULL; p = p->child) {
- put(p->key, p->value);
- }
}
-
-}
-
#endif // ANDROID_UTILS_LRU_CACHE_H
diff --git a/include/utils/String16.h b/include/utils/String16.h
index b2ab5dc..9a67c7a 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -65,8 +65,6 @@
inline const char16_t* string() const;
- const SharedBuffer* sharedBuffer() const;
-
size_t size() const;
void setTo(const String16& other);
status_t setTo(const char16_t* other);
diff --git a/include/utils/String8.h b/include/utils/String8.h
index a8a37db..2a75b98 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -28,7 +28,6 @@
namespace android {
-class SharedBuffer;
class String16;
class TextOutput;
@@ -69,7 +68,6 @@
inline bool isEmpty() const;
size_t length() const;
- const SharedBuffer* sharedBuffer() const;
void clear();
diff --git a/libutils/String16.cpp b/libutils/String16.cpp
index 67be9d8..6a5273f 100644
--- a/libutils/String16.cpp
+++ b/libutils/String16.cpp
@@ -171,11 +171,6 @@
return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1;
}
-const SharedBuffer* String16::sharedBuffer() const
-{
- return SharedBuffer::bufferFromData(mString);
-}
-
void String16::setTo(const String16& other)
{
SharedBuffer::bufferFromData(other.mString)->acquire();
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 5e85520..81bfccf 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -217,11 +217,6 @@
return SharedBuffer::sizeFromData(mString)-1;
}
-const SharedBuffer* String8::sharedBuffer() const
-{
- return SharedBuffer::bufferFromData(mString);
-}
-
String8 String8::format(const char* fmt, ...)
{
va_list args;
diff --git a/libutils/tests/LruCache_test.cpp b/libutils/tests/LruCache_test.cpp
index 6155def..2ed84d7 100644
--- a/libutils/tests/LruCache_test.cpp
+++ b/libutils/tests/LruCache_test.cpp
@@ -221,7 +221,7 @@
cache.put(ComplexKey(0), ComplexValue(0));
cache.put(ComplexKey(1), ComplexValue(1));
EXPECT_EQ(2U, cache.size());
- assertInstanceCount(2, 3); // the null value counts as an instance
+ assertInstanceCount(2, 3); // the member mNullValue counts as an instance
}
TEST_F(LruCacheTest, Clear) {