Add enforcement of idmap policies

Teaches idmap2 to recognize policy restrictions put on overlayable
resources. If overlayable enforcement is turned on for an overlay, then
any resources defined within the overlayable api of the target will have
policy restrictions imposed on them. All resources without overlayable
definitions will continue to be overlayable without policy restrictions.

Bug: 119390857
Test: atest idmap2 and booting

Co-authored-by: Ryan Mitchell <rtmitchell@google.com>
Change-Id: I7e435648eb6e4a87b0b90a7b2a0c3f33c1516ea6
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index d2e46e1..a3c7527 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -26,12 +26,15 @@
 #include <string>
 
 #include "android-base/macros.h"
+#include "android-base/stringprintf.h"
 #include "utils/String8.h"
 #include "utils/Trace.h"
 
 #include "idmap2/BinaryStreamVisitor.h"
 #include "idmap2/FileUtils.h"
 #include "idmap2/Idmap.h"
+#include "idmap2/Policies.h"
+#include "idmap2/Result.h"
 
 #include "idmap2d/Idmap2Service.h"
 
@@ -39,6 +42,8 @@
 using android::idmap2::BinaryStreamVisitor;
 using android::idmap2::Idmap;
 using android::idmap2::IdmapHeader;
+using android::idmap2::PolicyBitmask;
+using android::idmap2::Result;
 using android::idmap2::utils::kIdmapFilePermissionMask;
 
 namespace {
@@ -54,6 +59,10 @@
   return Status::fromExceptionCode(Status::EX_NONE, msg.c_str());
 }
 
+PolicyBitmask ConvertAidlArgToPolicyBitmask(int32_t arg) {
+  return static_cast<PolicyBitmask>(arg);
+}
+
 }  // namespace
 
 namespace android::os {
@@ -78,6 +87,8 @@
 }
 
 Status Idmap2Service::verifyIdmap(const std::string& overlay_apk_path,
+                                  int32_t fulfilled_policies ATTRIBUTE_UNUSED,
+                                  bool enforce_overlayable ATTRIBUTE_UNUSED,
                                   int32_t user_id ATTRIBUTE_UNUSED, bool* _aidl_return) {
   assert(_aidl_return);
   const std::string idmap_path = Idmap::CanonicalIdmapPathFor(kIdmapCacheDir, overlay_apk_path);
@@ -86,11 +97,15 @@
   fin.close();
   std::stringstream dev_null;
   *_aidl_return = header && header->IsUpToDate(dev_null);
+
+  // TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed
+
   return ok();
 }
 
 Status Idmap2Service::createIdmap(const std::string& target_apk_path,
-                                  const std::string& overlay_apk_path, int32_t user_id,
+                                  const std::string& overlay_apk_path, int32_t fulfilled_policies,
+                                  bool enforce_overlayable, int32_t user_id,
                                   std::unique_ptr<std::string>* _aidl_return) {
   assert(_aidl_return);
   std::stringstream trace;
@@ -101,6 +116,8 @@
 
   _aidl_return->reset(nullptr);
 
+  const PolicyBitmask policy_bitmask = ConvertAidlArgToPolicyBitmask(fulfilled_policies);
+
   const std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
   if (!target_apk) {
     return error("failed to load apk " + target_apk_path);
@@ -113,7 +130,8 @@
 
   std::stringstream err;
   const std::unique_ptr<const Idmap> idmap =
-      Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, err);
+      Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
+                           policy_bitmask, enforce_overlayable, err);
   if (!idmap) {
     return error(err.str());
   }
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h
index e0bc22e..1aab059 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.h
+++ b/cmds/idmap2/idmap2d/Idmap2Service.h
@@ -39,11 +39,12 @@
   binder::Status removeIdmap(const std::string& overlay_apk_path, int32_t user_id,
                              bool* _aidl_return);
 
-  binder::Status verifyIdmap(const std::string& overlay_apk_path, int32_t user_id,
-                             bool* _aidl_return);
+  binder::Status verifyIdmap(const std::string& overlay_apk_path, int32_t fulfilled_policies,
+                             bool enforce_overlayable, int32_t user_id, bool* _aidl_return);
 
   binder::Status createIdmap(const std::string& target_apk_path,
-                             const std::string& overlay_apk_path, int32_t user_id,
+                             const std::string& overlay_apk_path, int32_t fulfilled_policies,
+                             bool enforce_overlayable, int32_t user_id,
                              std::unique_ptr<std::string>* _aidl_return);
 };
 
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
index d475417..ea7274f 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
@@ -20,9 +20,18 @@
  * @hide
  */
 interface IIdmap2 {
+  const int POLICY_PUBLIC = 0x00000001;
+  const int POLICY_SYSTEM_PARTITION = 0x00000002;
+  const int POLICY_VENDOR_PARTITION = 0x00000004;
+  const int POLICY_PRODUCT_PARTITION = 0x00000008;
+
   @utf8InCpp String getIdmapPath(@utf8InCpp String overlayApkPath, int userId);
   boolean removeIdmap(@utf8InCpp String overlayApkPath, int userId);
-  boolean verifyIdmap(@utf8InCpp String overlayApkPath, int userId);
+  boolean verifyIdmap(@utf8InCpp String overlayApkPath, int fulfilledPolicies,
+                      boolean enforceOverlayable, int userId);
   @nullable @utf8InCpp String createIdmap(@utf8InCpp String targetApkPath,
-                                          @utf8InCpp String overlayApkPath, int userId);
+                                          @utf8InCpp String overlayApkPath,
+                                          int fulfilledPolicies,
+                                          boolean enforceOverlayable,
+                                          int userId);
 }