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

Commit 432d8be9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Migrate Permission APIs to BinderResult" into main

parents 8f4ff60a b05f2f13
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@
#include <cutils/android_filesystem_config.h>
#include <utils/Errors.h>

using ::android::base::unexpected;
using ::android::binder::Status;
using ::android::error::Result;
using ::android::error::BinderResult;
using ::android::error::unexpectedExceptionCode;

namespace com::android::media::permission {
static std::optional<std::string> getFixedPackageName(uid_t uid) {
@@ -103,23 +103,31 @@ Status NativePermissionController::populatePermissionState(PermissionEnum perm,

// -- End Binder methods

Result<std::vector<std::string>> NativePermissionController::getPackagesForUid(uid_t uid) const {
BinderResult<std::vector<std::string>> NativePermissionController::getPackagesForUid(
        uid_t uid) const {
    uid = uid % AID_USER_OFFSET;
    const auto fixed_package_opt = getFixedPackageName(uid);
    if (fixed_package_opt.has_value()) {
        return Result<std::vector<std::string>>{std::in_place_t{}, {fixed_package_opt.value()}};
        return BinderResult<std::vector<std::string>>{std::in_place_t{},
                                                      {fixed_package_opt.value()}};
    }
    std::lock_guard l{m_};
    if (!is_package_populated_) return unexpected{::android::NO_INIT};
    if (!is_package_populated_) {
        return unexpectedExceptionCode(
                Status::EX_ILLEGAL_STATE,
                "NPC::getPackagesForUid: controller never populated by system_server");
    }
    const auto cursor = package_map_.find(uid);
    if (cursor != package_map_.end()) {
        return cursor->second;
    } else {
        return unexpected{::android::BAD_VALUE};
        return unexpectedExceptionCode(
                Status::EX_ILLEGAL_ARGUMENT,
                ("NPC::getPackagesForUid: uid not found: " + std::to_string(uid)).c_str());
    }
}

Result<bool> NativePermissionController::validateUidPackagePair(
BinderResult<bool> NativePermissionController::validateUidPackagePair(
        uid_t uid, const std::string& packageName) const {
    uid = uid % AID_USER_OFFSET;
    const auto fixed_package_opt = getFixedPackageName(uid);
@@ -127,20 +135,27 @@ Result<bool> NativePermissionController::validateUidPackagePair(
        return packageName == fixed_package_opt.value();
    }
    std::lock_guard l{m_};
    if (!is_package_populated_) return unexpected{::android::NO_INIT};
    if (!is_package_populated_) {
        return unexpectedExceptionCode(
                Status::EX_ILLEGAL_STATE,
                "NPC::validatedUidPackagePair: controller never populated by system_server");
    }
    const auto cursor = package_map_.find(uid);
    return (cursor != package_map_.end()) &&
           (std::find(cursor->second.begin(), cursor->second.end(), packageName) !=
            cursor->second.end());
}

Result<bool> NativePermissionController::checkPermission(PermissionEnum perm, uid_t uid) const {
BinderResult<bool> NativePermissionController::checkPermission(PermissionEnum perm,
                                                               uid_t uid) const {
    std::lock_guard l{m_};
    const auto& uids = permission_map_[static_cast<size_t>(perm)];
    if (!uids.empty()) {
        return std::binary_search(uids.begin(), uids.end(), uid);
    } else {
        return unexpected{::android::NO_INIT};
        return unexpectedExceptionCode(
                Status::EX_ILLEGAL_STATE,
                "NPC::checkPermission: controller never populated by system_server");
    }
}

+15 −7
Original line number Diff line number Diff line
@@ -20,31 +20,39 @@
#include <error/expected_utils.h>
#include <utils/Log.h>

namespace com::android::media::permission {
using ::android::binder::Status;
using ::android::error::BinderResult;
using ::android::error::unexpectedExceptionCode;

using ::android::base::unexpected;
namespace com::android::media::permission {

Result<ValidatedAttributionSourceState> ValidatedAttributionSourceState::createFromBinderContext(
        AttributionSourceState attr, const IPermissionProvider& provider) {
BinderResult<ValidatedAttributionSourceState>
ValidatedAttributionSourceState::createFromBinderContext(AttributionSourceState attr,
                                                         const IPermissionProvider& provider) {
    attr.pid = ::android::IPCThreadState::self()->getCallingPid();
    attr.uid = ::android::IPCThreadState::self()->getCallingUid();
    return createFromTrustedUidNoPackage(std::move(attr), provider);
}

Result<ValidatedAttributionSourceState>
BinderResult<ValidatedAttributionSourceState>
ValidatedAttributionSourceState::createFromTrustedUidNoPackage(
        AttributionSourceState attr, const IPermissionProvider& provider) {
    if (attr.packageName.has_value() && attr.packageName->size() != 0) {
        if (VALUE_OR_RETURN(provider.validateUidPackagePair(attr.uid, attr.packageName.value()))) {
            return ValidatedAttributionSourceState{std::move(attr)};
        } else {
            return unexpected{::android::PERMISSION_DENIED};
            return unexpectedExceptionCode(Status::EX_SECURITY,
                                           attr.toString()
                                                   .insert(0, ": invalid attr ")
                                                   .insert(0, __PRETTY_FUNCTION__)
                                                   .c_str());
        }
    } else {
        // For APIs which don't appropriately pass attribution sources or packages, we need
        // to populate the package name with our best guess.
        const auto packageNames = VALUE_OR_RETURN(provider.getPackagesForUid(attr.uid));
        LOG_ALWAYS_FATAL_IF(packageNames.empty());
        LOG_ALWAYS_FATAL_IF(packageNames.empty(), "%s BUG: empty package list from controller",
                            __PRETTY_FUNCTION__);
        attr.packageName = std::move(packageNames[0]);
        return ValidatedAttributionSourceState{std::move(attr)};
    }
+8 −7
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
#include <vector>

#include <com/android/media/permission/PermissionEnum.h>
#include <error/Result.h>
#include <error/BinderResult.h>

namespace com::android::media::permission {

@@ -31,18 +31,19 @@ class IPermissionProvider {
    // Get all package names which run under a certain app-id. Returns non-empty.
    // Not user specific, since packages are across users. Special app-ids (system,
    // shell, etc.) are handled.  Fails if the provider does not know about the
    // app-id.
    virtual ::android::error::Result<std::vector<std::string>> getPackagesForUid(
    // app-id or if the provider has not been initialized.
    virtual ::android::error::BinderResult<std::vector<std::string>> getPackagesForUid(
            uid_t uid) const = 0;
    // True iff the provided package name runs under the app-id of uid.
    // Special app-ids (system, shell, etc.) are handled.
    // Fails if the provider does not know about the app-id.
    virtual ::android::error::Result<bool> validateUidPackagePair(
    // Fails if the provider does not know about the app-id or if the provider has not been
    // initialized.
    virtual ::android::error::BinderResult<bool> validateUidPackagePair(
            uid_t uid, const std::string& packageName) const = 0;

    // True iff the uid holds the permission (user aware).
    // Fails with NO_INIT if cache hasn't been populated.
    virtual ::android::error::Result<bool> checkPermission(PermissionEnum permission,
    virtual ::android::error::BinderResult<bool> checkPermission(PermissionEnum permission,
                                                                 uid_t uid) const = 0;
    virtual ~IPermissionProvider() = default;
};
+6 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <android-base/thread_annotations.h>
#include <com/android/media/permission/BnNativePermissionController.h>
#include <error/BinderResult.h>

namespace com::android::media::permission {

@@ -36,10 +37,11 @@ class NativePermissionController : public BnNativePermissionController, public I
    Status populatePermissionState(PermissionEnum permission, const std::vector<int>& uids) final;
    // end binder methods

    ::android::error::Result<std::vector<std::string>> getPackagesForUid(uid_t uid) const final;
    ::android::error::Result<bool> validateUidPackagePair(
    ::android::error::BinderResult<std::vector<std::string>> getPackagesForUid(
            uid_t uid) const final;
    ::android::error::BinderResult<bool> validateUidPackagePair(
            uid_t uid, const std::string& packageName) const final;
    ::android::error::Result<bool> checkPermission(PermissionEnum permission,
    ::android::error::BinderResult<bool> checkPermission(PermissionEnum permission,
                                                         uid_t uid) const final;

  private:
+7 −6
Original line number Diff line number Diff line
@@ -17,22 +17,22 @@
#pragma once

#include <android/content/AttributionSourceState.h>
#include <error/Result.h>
#include <error/BinderResult.h>

#include "IPermissionProvider.h"

namespace com::android::media::permission {

using ::android::content::AttributionSourceState;
using ::android::error::Result;

class ValidatedAttributionSourceState {
  public:
    /**
     * Validates an attribution source from within the context of a binder transaction.
     * Overwrites the uid/pid and validates the packageName
     * Overwrites the uid/pid and validates the packageName.
     * Returns EX_SECURITY on package validation fail.
     */
    static Result<ValidatedAttributionSourceState> createFromBinderContext(
    static ::android::error::BinderResult<ValidatedAttributionSourceState> createFromBinderContext(
            AttributionSourceState attr, const IPermissionProvider& provider);

    /**
@@ -47,9 +47,10 @@ class ValidatedAttributionSourceState {
     * Create a ValidatedAttribubtionSourceState in cases where the uid/pid is trusted, but the
     * packages have not been validated. Proper use of the previous two methods should avoid the
     * necessity of this, but it is useful for migration purposes as well as testing this class.
     * Returns EX_SECURITY on package validation fail.
     */
    static Result<ValidatedAttributionSourceState> createFromTrustedUidNoPackage(
            AttributionSourceState attr, const IPermissionProvider& provider);
    static ::android::error::BinderResult<ValidatedAttributionSourceState>
    createFromTrustedUidNoPackage(AttributionSourceState attr, const IPermissionProvider& provider);

    operator AttributionSourceState() const { return state_; }

Loading