Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e11bfbe4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "idmap-default-policies"

* changes:
  Fix idmap scan to supply correct policies
  Revert "Revert "Enforce a default policy on packages without <overlayable>""
parents 8e97c359 4c09a4a4
Loading
Loading
Loading
Loading
+22 −21
Original line number Diff line number Diff line
@@ -38,7 +38,10 @@

using android::idmap2::CommandLineOptions;
using android::idmap2::Idmap;
using android::idmap2::PoliciesToBitmask;
using android::idmap2::kPolicyProduct;
using android::idmap2::kPolicyPublic;
using android::idmap2::kPolicySystem;
using android::idmap2::kPolicyVendor;
using android::idmap2::PolicyBitmask;
using android::idmap2::PolicyFlags;
using android::idmap2::Result;
@@ -87,20 +90,22 @@ std::unique_ptr<std::vector<std::string>> FindApkFiles(const std::vector<std::st
  return std::make_unique<std::vector<std::string>>(paths.cbegin(), paths.cend());
}

PolicyBitmask PolicyForPath(const std::string& apk_path) {
  static const std::vector<std::pair<std::string, PolicyBitmask>> values = {
      {"/product/", PolicyFlags::POLICY_PRODUCT_PARTITION},
      {"/system/", PolicyFlags::POLICY_SYSTEM_PARTITION},
      {"/vendor/", PolicyFlags::POLICY_VENDOR_PARTITION},
std::vector<std::string> PoliciesForPath(const std::string& apk_path) {
  static const std::vector<std::pair<std::string, std::string>> values = {
      {"/product/", kPolicyProduct},
      {"/system/", kPolicySystem},
      {"/vendor/", kPolicyVendor},
  };

  std::vector<std::string> fulfilled_policies = {kPolicyPublic};
  for (auto const& pair : values) {
    if (apk_path.compare(0, pair.first.size(), pair.first) == 0) {
      return pair.second | PolicyFlags::POLICY_PUBLIC;
      fulfilled_policies.emplace_back(pair.second);
      break;
    }
  }

  return PolicyFlags::POLICY_PUBLIC;
  return fulfilled_policies;
}

}  // namespace
@@ -161,21 +166,17 @@ bool Scan(const std::vector<std::string>& args, std::ostream& out_error) {
      continue;
    }

    PolicyBitmask fulfilled_policies;
    std::vector<std::string> fulfilled_policies;
    if (!override_policies.empty()) {
      auto conv_result = PoliciesToBitmask(override_policies);
      if (conv_result) {
        fulfilled_policies = *conv_result;
      fulfilled_policies = override_policies;
    } else {
        out_error << "error: " << conv_result.GetErrorMessage() << std::endl;
        return false;
      }
    } else {
      fulfilled_policies = PolicyForPath(path);
      fulfilled_policies = PoliciesForPath(path);
    }

    bool ignore_overlayable = false;
    if ((fulfilled_policies & PolicyFlags::POLICY_VENDOR_PARTITION) != 0 && !VendorIsQOrLater()) {
    if (std::find(fulfilled_policies.begin(), fulfilled_policies.end(), kPolicyVendor) !=
            fulfilled_policies.end() &&
        !VendorIsQOrLater()) {
      // If the overlay is on a pre-Q vendor partition, do not enforce overlayable
      // restrictions on this overlay because the pre-Q platform has no understanding of
      // overlayable.
@@ -185,7 +186,7 @@ bool Scan(const std::vector<std::string>& args, std::ostream& out_error) {
    std::string idmap_path = Idmap::CanonicalIdmapPathFor(output_directory, path);

    // Sort the static overlays in ascending priority order
    InputOverlay input{path, idmap_path, overlay_info->priority, override_policies,
    InputOverlay input{path, idmap_path, overlay_info->priority, fulfilled_policies,
                       ignore_overlayable};
    interesting_apks.insert(
        std::lower_bound(interesting_apks.begin(), interesting_apks.end(), input), input);
@@ -211,8 +212,8 @@ bool Scan(const std::vector<std::string>& args, std::ostream& out_error) {
      }

      for (const std::string& policy : overlay.policies) {
        verify_args.emplace_back("--policy");
        verify_args.emplace_back(policy);
        create_args.emplace_back("--policy");
        create_args.emplace_back(policy);
      }

      if (!Create(create_args, out_error)) {
+10 −2
Original line number Diff line number Diff line
@@ -27,13 +27,21 @@

namespace android::idmap2 {

constexpr const char* kPolicyPublic = "public";
constexpr const char* kPolicyProduct = "product";
constexpr const char* kPolicySystem = "system";
constexpr const char* kPolicyVendor = "vendor";
constexpr const char* kPolicySignature = "signature";

using PolicyFlags = ResTable_overlayable_policy_header::PolicyFlags;
using PolicyBitmask = uint32_t;

// Parses a the string representation of a set of policies into a bitmask. The format of the string
// is the same as for the <policy> element.
// Parses the string representations of policies into a bitmask.
Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies);

// Retrieves the string representations of policies in the bitmask.
std::vector<std::string> BitmaskToPolicies(const PolicyBitmask& bitmask);

}  // namespace android::idmap2

#endif  // IDMAP2_INCLUDE_IDMAP2_POLICIES_H_
+57 −13
Original line number Diff line number Diff line
@@ -285,24 +285,58 @@ std::unique_ptr<const Idmap> Idmap::FromBinaryStream(std::istream& stream,
  return std::move(idmap);
}

bool CheckOverlayable(const LoadedPackage& target_package,
std::string ConcatPolicies(const std::vector<std::string>& policies) {
  std::string message;
  for (const std::string& policy : policies) {
    if (message.empty()) {
      message.append(policy);
    } else {
      message.append(policy);
      message.append("|");
    }
  }

  return message;
}

Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
                              const utils::OverlayManifestInfo& overlay_info,
                              const PolicyBitmask& fulfilled_policies, const ResourceId& resid) {
  static constexpr const PolicyBitmask sDefaultPolicies =
      PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION |
      PolicyFlags::POLICY_PRODUCT_PARTITION | PolicyFlags::POLICY_SIGNATURE;

  // If the resource does not have an overlayable definition, allow the resource to be overlaid if
  // the overlay is preinstalled or signed with the same signature as the target.
  if (!target_package.DefinesOverlayable()) {
    return (sDefaultPolicies & fulfilled_policies) != 0
               ? Result<Unit>({})
               : Error(
                     "overlay must be preinstalled or signed with the same signature as the "
                     "target");
  }

  const OverlayableInfo* overlayable_info = target_package.GetOverlayableInfo(resid);
  if (overlayable_info == nullptr) {
    // If the resource does not have an overlayable definition, allow the resource to be overlaid.
    // Once overlayable enforcement is turned on, this check will return false.
    return !target_package.DefinesOverlayable();
    // Do not allow non-overlayable resources to be overlaid.
    return Error("resource has no overlayable declaration");
  }

  if (overlay_info.target_name != overlayable_info->name) {
    // If the overlay supplies a target overlayable name, the resource must belong to the
    // overlayable defined with the specified name to be overlaid.
    return false;
    return Error("<overlay> android:targetName '%s' does not match overlayable name '%s'",
                 overlay_info.target_name.c_str(), overlayable_info->name.c_str());
  }

  // Enforce policy restrictions if the resource is declared as overlayable.
  return (overlayable_info->policy_flags & fulfilled_policies) != 0;
  if ((overlayable_info->policy_flags & fulfilled_policies) == 0) {
    return Error("overlay with policies '%s' does not fulfill any overlayable policies '%s'",
                 ConcatPolicies(BitmaskToPolicies(fulfilled_policies)).c_str(),
                 ConcatPolicies(BitmaskToPolicies(overlayable_info->policy_flags)).c_str());
  }

  return Result<Unit>({});
}

std::unique_ptr<const Idmap> Idmap::FromApkAssets(
@@ -418,16 +452,26 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets(
      continue;
    }

    if (enforce_overlayable &&
        !CheckOverlayable(*target_pkg, *overlay_info, fulfilled_policies, target_resid)) {
      LOG(WARNING) << "overlay \"" << overlay_apk_path << "\" is not allowed to overlay resource \""
                   << full_name << "\"" << std::endl;
    if (!enforce_overlayable) {
      Result<Unit> success =
          CheckOverlayable(*target_pkg, *overlay_info, fulfilled_policies, target_resid);
      if (!success) {
        LOG(WARNING) << "overlay \"" << overlay_apk_path
                     << "\" is not allowed to overlay resource \"" << full_name
                     << "\": " << success.GetErrorMessage();
        continue;
      }
    }

    matching_resources.Add(target_resid, overlay_resid);
  }

  if (matching_resources.Map().empty()) {
    out_error << "overlay \"" << overlay_apk_path << "\" does not successfully overlay any resource"
              << std::endl;
    return nullptr;
  }

  // encode idmap data
  std::unique_ptr<IdmapData> data(new IdmapData());
  const auto types_end = matching_resources.Map().cend();
+31 −5
Original line number Diff line number Diff line
@@ -30,12 +30,13 @@ namespace android::idmap2 {
namespace {

const std::map<android::StringPiece, PolicyFlags> kStringToFlag = {
    {"public", PolicyFlags::POLICY_PUBLIC},
    {"product", PolicyFlags::POLICY_PRODUCT_PARTITION},
    {"system", PolicyFlags::POLICY_SYSTEM_PARTITION},
    {"vendor", PolicyFlags::POLICY_VENDOR_PARTITION},
    {"signature", PolicyFlags::POLICY_SIGNATURE},
    {kPolicyPublic, PolicyFlags::POLICY_PUBLIC},
    {kPolicyProduct, PolicyFlags::POLICY_PRODUCT_PARTITION},
    {kPolicySystem, PolicyFlags::POLICY_SYSTEM_PARTITION},
    {kPolicyVendor, PolicyFlags::POLICY_VENDOR_PARTITION},
    {kPolicySignature, PolicyFlags::POLICY_SIGNATURE},
};

}  // namespace

Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies) {
@@ -52,4 +53,29 @@ Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies
  return Result<PolicyBitmask>(bitmask);
}

std::vector<std::string> BitmaskToPolicies(const PolicyBitmask& bitmask) {
  std::vector<std::string> policies;
  if ((bitmask & PolicyFlags::POLICY_PUBLIC) != 0) {
    policies.emplace_back(kPolicyPublic);
  }

  if ((bitmask & PolicyFlags::POLICY_PRODUCT_PARTITION) != 0) {
    policies.emplace_back(kPolicyProduct);
  }

  if ((bitmask & PolicyFlags::POLICY_SYSTEM_PARTITION) != 0) {
    policies.emplace_back(kPolicySystem);
  }

  if ((bitmask & PolicyFlags::POLICY_VENDOR_PARTITION) != 0) {
    policies.emplace_back(kPolicyVendor);
  }

  if ((bitmask & PolicyFlags::POLICY_SIGNATURE) != 0) {
    policies.emplace_back(kPolicySignature);
  }

  return policies;
}

}  // namespace android::idmap2
+118 −156

File changed.

Preview size limit exceeded, changes collapsed.

Loading