Merge the 2021-02-05 SPL branch from AOSP-Partner

* security-aosp-pi-release:
  storaged: protect global proto_loaded
  Fix storaged memory leak
  FileMap::create: remove duplicate addition.
  Fail explicitly on length overflow.

Change-Id: Id781289fd0b3b22a1037fd623925d8c52a6a7278
diff --git a/libutils/FileMap.cpp b/libutils/FileMap.cpp
index 3c4d81c..f6fe03f 100644
--- a/libutils/FileMap.cpp
+++ b/libutils/FileMap.cpp
@@ -168,12 +168,6 @@
         return false;
     }
 #else // !defined(__MINGW32__)
-    int     prot, flags, adjust;
-    off64_t adjOffset;
-    size_t  adjLength;
-
-    void* ptr;
-
     assert(fd >= 0);
     assert(offset >= 0);
     assert(length > 0);
@@ -187,16 +181,19 @@
         }
     }
 
-    adjust = offset % mPageSize;
-    adjOffset = offset - adjust;
-    adjLength = length + adjust;
+    int adjust = offset % mPageSize;
+    off64_t adjOffset = offset - adjust;
+    size_t adjLength;
+    if (__builtin_add_overflow(length, adjust, &adjLength)) {
+        ALOGE("adjusted length overflow: length %zu adjust %d", length, adjust);
+        return false;
+    }
 
-    flags = MAP_SHARED;
-    prot = PROT_READ;
-    if (!readOnly)
-        prot |= PROT_WRITE;
+    int flags = MAP_SHARED;
+    int prot = PROT_READ;
+    if (!readOnly) prot |= PROT_WRITE;
 
-    ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset);
+    void* ptr = mmap(nullptr, adjLength, prot, flags, fd, adjOffset);
     if (ptr == MAP_FAILED) {
         ALOGE("mmap(%lld,%zu) failed: %s\n",
             (long long)adjOffset, adjLength, strerror(errno));
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 400e734..a3d05e5 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -87,6 +87,7 @@
     sp<android::hardware::health::V2_0::IHealth> health;
     unique_ptr<storage_info_t> storage_info;
     static const uint32_t current_version;
+    Mutex proto_lock;
     unordered_map<userid_t, bool> proto_loaded;
     void load_proto(userid_t user_id);
     char* prepare_proto(userid_t user_id, StoragedProto* proto);
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index bf8b448..53da6a3 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -163,11 +163,17 @@
 }
 
 void storaged_t::add_user_ce(userid_t user_id) {
-    load_proto(user_id);
-    proto_loaded[user_id] = true;
+    Mutex::Autolock _l(proto_lock);
+
+    if (!proto_loaded[user_id]) {
+        load_proto(user_id);
+        proto_loaded[user_id] = true;
+    }
 }
 
 void storaged_t::remove_user_ce(userid_t user_id) {
+    Mutex::Autolock _l(proto_lock);
+
     proto_loaded[user_id] = false;
     mUidm.clear_user_history(user_id);
     RemoveFileIfExists(proto_path(user_id), nullptr);
@@ -298,6 +304,8 @@
 }
 
 void storaged_t::flush_protos(unordered_map<int, StoragedProto>* protos) {
+    Mutex::Autolock _l(proto_lock);
+
     for (auto& it : *protos) {
         /*
          * Don't flush proto if we haven't attempted to load it from file.