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

Commit 0555fbf9 authored by Devin Moore's avatar Devin Moore
Browse files

Add a method for libbinder to wrap an accessor in a delegator

Libbinder is the only place with the IAccessorDelegator class so it must
be responsible for wrapping the IAccesses with an IAccessorDelegator.

This is used when the process with the permissions to connect to the
server over binder RPC is in a seperate process from the process that
wants to serve the IAccessor binder.

Test: atest vm_accessor_test binderRpcTest
Bug: 358427181

Change-Id: I0839f7d1b466ba9bfb13031596523314718d3677
parent 51b2f8f1
Loading
Loading
Loading
Loading
+2 −21
Original line number Diff line number Diff line
@@ -489,6 +489,7 @@ cc_defaults {
        "ProcessState.cpp",
        "Static.cpp",
        ":libbinder_aidl",
        ":libbinder_accessor_aidl",
        ":libbinder_device_interface_sources",
    ],
    target: {
@@ -801,7 +802,6 @@ filegroup {
        "aidl/android/os/IServiceManager.aidl",
        "aidl/android/os/Service.aidl",
        "aidl/android/os/ServiceDebugInfo.aidl",
        ":libbinder_accessor_aidl",
    ],
    path: "aidl",
}
@@ -812,26 +812,7 @@ filegroup {
        "aidl/android/os/IAccessor.aidl",
    ],
    path: "aidl",
}

// TODO(b/353492849): Make this interface private to libbinder.
aidl_interface {
    name: "android.os.accessor",
    srcs: [":libbinder_accessor_aidl"],
    unstable: true,
    backend: {
        rust: {
            enabled: true,
            apex_available: [
                "com.android.virt",
            ],
        },
    },
    visibility: [
        ":__subpackages__",
        "//system/tools/aidl:__subpackages__",
        "//packages/modules/Virtualization:__subpackages__",
    ],
    visibility: [":__subpackages__"],
}

aidl_interface {
+23 −1
Original line number Diff line number Diff line
@@ -386,7 +386,7 @@ status_t validateAccessor(const String16& instance, const sp<IBinder>& binder) {
        ALOGE("Binder is null");
        return BAD_VALUE;
    }
    sp<IAccessor> accessor = interface_cast<IAccessor>(binder);
    sp<IAccessor> accessor = checked_interface_cast<IAccessor>(binder);
    if (accessor == nullptr) {
        ALOGE("This binder for %s is not an IAccessor binder", String8(instance).c_str());
        return BAD_TYPE;
@@ -420,6 +420,28 @@ sp<IBinder> createAccessor(const String16& instance,
    return binder;
}

status_t delegateAccessor(const String16& name, const sp<IBinder>& accessor,
                          sp<IBinder>* delegator) {
    LOG_ALWAYS_FATAL_IF(delegator == nullptr, "delegateAccessor called with a null out param");
    if (accessor == nullptr) {
        ALOGW("Accessor argument to delegateAccessor is null.");
        *delegator = nullptr;
        return OK;
    }
    status_t status = validateAccessor(name, accessor);
    if (status != OK) {
        ALOGE("The provided accessor binder is not an IAccessor for instance %s. Status: "
              "%s",
              String8(name).c_str(), statusToString(status).c_str());
        return status;
    }
    // validateAccessor already called checked_interface_cast and made sure this
    // is a valid accessor object.
    *delegator = sp<android::os::IAccessorDelegator>::make(interface_cast<IAccessor>(accessor));

    return OK;
}

#if !defined(__ANDROID_VNDK__)
// IPermissionController is not accessible to vendors

+22 −0
Original line number Diff line number Diff line
@@ -291,6 +291,28 @@ LIBBINDER_EXPORTED sp<IBinder> createAccessor(const String16& instance,
 * \return OK if the binder is an IAccessor for `instance`
 */
LIBBINDER_EXPORTED status_t validateAccessor(const String16& instance, const sp<IBinder>& binder);

/**
 * Have libbinder wrap this IAccessor binder in an IAccessorDelegator and return
 * it.
 *
 * This is required only in very specific situations when the process that has
 * permissions to connect the to RPC service's socket and create the FD for it
 * is in a separate process from this process that wants to service the Accessor
 * binder and the communication between these two processes is binder RPC. This
 * is needed because the binder passed over the binder RPC connection can not be
 * used as a kernel binder, and needs to be wrapped by a kernel binder that can
 * then be registered with service manager.
 *
 * \param instance name of the Accessor.
 * \param binder to wrap in a Delegator and register with service manager.
 * \param outDelegator the wrapped kernel binder for IAccessorDelegator
 *
 * \return OK if the binder is an IAccessor for `instance` and the delegator was
 * successfully created.
 */
LIBBINDER_EXPORTED status_t delegateAccessor(const String16& name, const sp<IBinder>& accessor,
                                             sp<IBinder>* delegator);
#endif // __TRUSTY__

#ifndef __ANDROID__
+22 −0
Original line number Diff line number Diff line
@@ -302,6 +302,28 @@ ABinderRpc_Accessor* ABinderRpc_Accessor_fromBinder(const char* instance, AIBind
    }
}

binder_status_t ABinderRpc_Accessor_delegateAccessor(const char* instance, AIBinder* accessor,
                                                     AIBinder** outDelegator) {
    LOG_ALWAYS_FATAL_IF(outDelegator == nullptr, "The outDelegator argument is null");
    if (instance == nullptr || accessor == nullptr) {
        ALOGW("instance or accessor arguments to ABinderRpc_Accessor_delegateBinder are null");
        *outDelegator = nullptr;
        return STATUS_UNEXPECTED_NULL;
    }
    sp<IBinder> accessorBinder = accessor->getBinder();

    sp<IBinder> delegator;
    status_t status = android::delegateAccessor(String16(instance), accessorBinder, &delegator);
    if (status != OK) {
        return PruneStatusT(status);
    }
    sp<AIBinder> binder = ABpBinder::lookupOrCreateFromBinder(delegator);
    // This AIBinder needs a strong ref to pass ownership to the caller
    binder->incStrong(nullptr);
    *outDelegator = binder.get();
    return OK;
}

ABinderRpc_ConnectionInfo* ABinderRpc_ConnectionInfo_new(const sockaddr* addr, socklen_t len) {
    if (addr == nullptr || len < 0 || static_cast<size_t>(len) < sizeof(sa_family_t)) {
        ALOGE("Invalid arguments in ABinderRpc_Connection_new");
+29 −0
Original line number Diff line number Diff line
@@ -264,6 +264,35 @@ ABinderRpc_Accessor* _Nullable ABinderRpc_Accessor_fromBinder(const char* _Nonnu
                                                              AIBinder* _Nonnull accessorBinder)
        __INTRODUCED_IN(36);

/**
 * Wrap an ABinderRpc_Accessor proxy binder with a delegator binder.
 *
 * The IAccessorDelegator binder delegates all calls to the proxy binder.
 *
 * This is required only in very specific situations when the process that has
 * permissions to connect the to RPC service's socket and create the FD for it
 * is in a separate process from this process that wants to serve the Accessor
 * binder and the communication between these two processes is binder RPC. This
 * is needed because the binder passed over the binder RPC connection can not be
 * used as a kernel binder, and needs to be wrapped by a kernel binder that can
 * then be registered with service manager.
 *
 * \param instance name of the service associated with the Accessor
 * \param binder the AIBinder* from the ABinderRpc_Accessor from the
 *        ABinderRpc_Accessor_asBinder. The other process across the binder RPC
 *        connection will have called this and passed the AIBinder* across a
 *        binder interface to the process calling this function.
 * \param outDelegator the AIBinder* for the kernel binder that wraps the
 *        'binder' argument and delegates all calls to it. The caller now owns
 *        this object with one strong ref count and is responsible for removing
 *        that ref count with with AIBinder_decStrong when the caller wishes to
 *        drop the reference.
 */
binder_status_t ABinderRpc_Accessor_delegateAccessor(const char* _Nonnull instance,
                                                     AIBinder* _Nonnull binder,
                                                     AIBinder* _Nullable* _Nonnull outDelegator)
        __INTRODUCED_IN(36);

/**
 * Create a new ABinderRpc_ConnectionInfo with sockaddr. This can be supported socket
 * types like sockaddr_vm (vsock) and sockaddr_un (Unix Domain Sockets).
Loading