[cfi] Adjust RLIMIT_AS by CFI shadow size.

CFI (control flow integrity) implementation is using a MAP_NORESERVE
allocation of up to 2GB is size. Only a tiny portion of it is backed
by physical memory. Take this into account when setting RLIMIT_AS for
media services.

Test: no immediate effect; CFI shadow increase for 48-bit aarch64 can
      be reapplied w/o breaking android boot.
Bug: 64293803

See https://android-review.googlesource.com/#/c/platform/bionic/+/424903/.

Change-Id: I8d4e780a8579f3102f97abe0f5c9bf8f3dee3d2f
diff --git a/media/libmedia/MediaUtils.cpp b/media/libmedia/MediaUtils.cpp
index dc2bc82..bcdc3bd 100644
--- a/media/libmedia/MediaUtils.cpp
+++ b/media/libmedia/MediaUtils.cpp
@@ -24,6 +24,8 @@
 
 #include "MediaUtils.h"
 
+extern "C" size_t __cfi_shadow_size();
+
 namespace android {
 
 void limitProcessMemory(
@@ -62,6 +64,19 @@
     if (propVal > 0 && uint64_t(propVal) <= SIZE_MAX) {
         maxMem = propVal;
     }
+
+    // Increase by the size of the CFI shadow mapping. Most of the shadow is not
+    // backed with physical pages, and it is possible for the result to be
+    // higher than total physical memory. This is fine for RLIMIT_AS.
+    size_t cfi_size = __cfi_shadow_size();
+    if (cfi_size) {
+      ALOGV("cfi shadow size: %zu", cfi_size);
+      if (maxMem <= SIZE_MAX - cfi_size) {
+        maxMem += cfi_size;
+      } else {
+        maxMem = SIZE_MAX;
+      }
+    }
     ALOGV("actual limit: %zu", maxMem);
 
     struct rlimit limit;