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

Commit a640fb9f authored by Devin Moore's avatar Devin Moore Committed by Android (Google) Code Review
Browse files

Merge changes from topic "avf_host_service_config" into main

* changes:
  Add rust APIs for new checkServiceAccess method in libbinder
  Add NDK APIs for new checkServiceAccess method in libbinder
  IServiceManager add checkServiceAccess to delegate sepolicy check
parents 9f56b1aa c662c5ed
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ class ServiceManagerMock : public IServiceManager {
                                             const sp<LocalRegistrationCallback>&));
    MOCK_METHOD0(getServiceDebugInfo, std::vector<ServiceDebugInfo>());
    MOCK_METHOD1(enableAddServiceCache, void(bool));
    MOCK_METHOD5(checkServiceAccess, bool(const String16&, pid_t, uid_t, const String16&, const String16&));

  protected:
    MOCK_METHOD0(onAsBinder, IBinder*());
+59 −0
Original line number Diff line number Diff line
@@ -1179,6 +1179,65 @@ Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outRet
    return Status::ok();
}

Status ServiceManager::checkServiceAccessImpl(const Access::CallingContext& ctx,
                                              const std::string& name,
                                              const std::string& permission, bool* outReturn) {
    *outReturn = false;
    if (permission == "find") {
        std::optional<std::string> _accessor;
        if (auto status = canFindService(ctx, name, &_accessor); !status.isOk()) {
            return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
        }
    } else if (permission == "add") {
        std::optional<std::string> _accessor;
        if (auto status = canAddService(ctx, name, &_accessor); !status.isOk()) {
            return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
        }
    } else if (permission == "list") {
        if (!mAccess->canList(ctx)) {
            return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
        }
    } else {
        ALOGE("Unknown service_manager permission: %s", permission.c_str());
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid permission");
    }

    *outReturn = true;
    return Status::ok();
}

Status ServiceManager::checkServiceAccess(const IServiceManager::CallerContext& callerCtx,
                                          const std::string& name, const std::string& permission,
                                          bool* outReturn) {
    if (callerCtx.sidName.empty() || name.empty() || permission.empty()) {
        return Status::
                fromExceptionCode(Status::EX_SECURITY,
                                  String8::format("Call to checkServiceAccess has incomplete "
                                                  "arguments. "
                                                  "the caller security context (sid): \"%s\", "
                                                  "name: \"%s\", permission: \"%s\".",
                                                  callerCtx.sidName.c_str(), name.c_str(),
                                                  permission.c_str()));
    }
    // The caller must have check_access permission
    Access::CallingContext directCallerCtx = mAccess->getCallingContext();
    // TODO add check_access permission in system/sepolicy/private/access_vectors
    // For now, the only user of this, virtmgr, already has access to these
    // services because it needs to proxy them.
    auto status = checkServiceAccessImpl(directCallerCtx, name, permission, outReturn);
    if (!status.isOk() || !*outReturn) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Caller is not allowed to delegate this check to "
                                         "servicemanager.");
    }

    Access::CallingContext callingCtx;
    callingCtx.debugPid = callerCtx.debugPid;
    callingCtx.uid = callerCtx.uid;
    callingCtx.sid = callerCtx.sidName;
    return checkServiceAccessImpl(callingCtx, name, permission, outReturn);
}

void ServiceManager::clear() {
    mNameToService.clear();
    mNameToRegistrationCallback.clear();
+6 −1
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ public:
                                          const sp<IClientCallback>& cb) override;
    binder::Status tryUnregisterService(const std::string& name, const sp<IBinder>& binder) override;
    binder::Status getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) override;
    binder::Status checkServiceAccess(const os::IServiceManager::CallerContext& callerCtx,
                                      const std::string& name, const std::string& permission,
                                      bool* outReturn) override;
    void binderDied(const wp<IBinder>& who) override;
    void handleClientCallbacks();

@@ -120,7 +123,9 @@ private:
                                 std::optional<std::string>* accessor);
    binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name,
                                  std::optional<std::string>* accessor);

    binder::Status checkServiceAccessImpl(const Access::CallingContext& ctx,
                                          const std::string& name, const std::string& permission,
                                          bool* outReturn);
    ServiceMap mNameToService;
    ServiceCallbackMap mNameToRegistrationCallback;
    ClientCallbackMap mNameToClientCallback;
+11 −0
Original line number Diff line number Diff line
@@ -473,6 +473,17 @@ Status BackendUnifiedServiceManager::getServiceDebugInfo(
                                     kUnsupportedOpNoServiceManager);
}

Status BackendUnifiedServiceManager::checkServiceAccess(
        const AidlServiceManager::CallerContext& callerCtx, const std::string& name,
        const std::string& permission, bool* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->checkServiceAccess(callerCtx, name, permission,
                                                          _aidl_return);
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}

[[clang::no_destroy]] static std::once_flag gUSmOnce;
[[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;

+4 −0
Original line number Diff line number Diff line
@@ -147,6 +147,10 @@ public:
                                        const sp<IBinder>& service) override;
    binder::Status getServiceDebugInfo(::std::vector<os::ServiceDebugInfo>* _aidl_return) override;

    binder::Status checkServiceAccess(const os::IServiceManager::CallerContext& callerCtx,
                                      const ::std::string& name, const ::std::string& permission,
                                      bool* _aidl_return) override;

    void enableAddServiceCache(bool value) { mEnableAddServiceCache = value; }
    // for legacy ABI
    const String16& getInterfaceDescriptor() const override {
Loading