Merge "Add permissions to modify raw_syscall filters."
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 25bd9a3..edeb2a4 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -113,6 +113,9 @@
     },
     srcs: ["ServiceManagerFuzzer.cpp"],
     fuzz_config: {
+        libfuzzer_options: [
+            "max_len=50000",
+        ],
         cc: [
             "smoreland@google.com",
             "waghpawan@google.com",
diff --git a/cmds/servicemanager/ServiceManagerFuzzer.cpp b/cmds/servicemanager/ServiceManagerFuzzer.cpp
index 9e2e53f..39f8522 100644
--- a/cmds/servicemanager/ServiceManagerFuzzer.cpp
+++ b/cmds/servicemanager/ServiceManagerFuzzer.cpp
@@ -26,13 +26,9 @@
 using ::android::sp;
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    if (size > 50000) {
-        return 0;
-    }
-
     auto accessPtr = std::make_unique<Access>();
     auto serviceManager = sp<ServiceManager>::make(std::move(accessPtr));
     fuzzService(serviceManager, FuzzedDataProvider(data, size));
 
     return 0;
-}
\ No newline at end of file
+}
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 441a4a8..fabf3eb 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -339,6 +339,34 @@
     defaults: ["libbinder_tls_defaults"],
 }
 
+cc_library_shared {
+    name: "libbinder_trusty",
+    vendor: true,
+    srcs: [
+        "RpcTransportTipcAndroid.cpp",
+        "RpcTrusty.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libtrusty",
+        "libutils",
+    ],
+    static_libs: [
+        "libbase",
+    ],
+    export_include_dirs: ["include_trusty"],
+
+    // Most of Android doesn't need this library and shouldn't use it,
+    // so we restrict its visibility to the Trusty-specific packages.
+    visibility: [
+        ":__subpackages__",
+        "//system/core/trusty:__subpackages__",
+        "//vendor:__subpackages__",
+    ],
+}
+
 // For testing
 cc_library_static {
     name: "libbinder_tls_static",
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index b5ea60f..1dc6233 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -202,6 +202,17 @@
     proxy->withLock(doWithLock);
 }
 
+sp<IBinder> IBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
+                                        const void* makeArgs) {
+    BBinder* local = localBinder();
+    if (local) {
+        return local->lookupOrCreateWeak(objectID, make, makeArgs);
+    }
+    BpBinder* proxy = this->remoteBinder();
+    LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote");
+    return proxy->lookupOrCreateWeak(objectID, make, makeArgs);
+}
+
 // ---------------------------------------------------------------------------
 
 class BBinder::RpcServerLink : public IBinder::DeathRecipient {
@@ -378,6 +389,14 @@
     doWithLock();
 }
 
+sp<IBinder> BBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
+                                        const void* makeArgs) {
+    Extras* e = getOrCreateExtras();
+    LOG_ALWAYS_FATAL_IF(!e, "no memory");
+    AutoMutex _l(e->mLock);
+    return e->mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
+}
+
 BBinder* BBinder::localBinder()
 {
     return this;
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index b6d35ef..d9b7231 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -100,6 +100,36 @@
     return value;
 }
 
+namespace {
+struct Tag {
+    wp<IBinder> binder;
+};
+} // namespace
+
+static void cleanWeak(const void* /* id */, void* obj, void* /* cookie */) {
+    delete static_cast<Tag*>(obj);
+}
+
+sp<IBinder> BpBinder::ObjectManager::lookupOrCreateWeak(const void* objectID, object_make_func make,
+                                                        const void* makeArgs) {
+    entry_t& e = mObjects[objectID];
+    if (e.object != nullptr) {
+        if (auto attached = static_cast<Tag*>(e.object)->binder.promote()) {
+            return attached;
+        }
+    } else {
+        e.object = new Tag;
+        LOG_ALWAYS_FATAL_IF(!e.object, "no more memory");
+    }
+    sp<IBinder> newObj = make(makeArgs);
+
+    static_cast<Tag*>(e.object)->binder = newObj;
+    e.cleanupCookie = nullptr;
+    e.func = cleanWeak;
+
+    return newObj;
+}
+
 void BpBinder::ObjectManager::kill()
 {
     const size_t N = mObjects.size();
@@ -516,6 +546,12 @@
     doWithLock();
 }
 
+sp<IBinder> BpBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
+                                         const void* makeArgs) {
+    AutoMutex _l(mLock);
+    return mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
+}
+
 BpBinder* BpBinder::remoteBinder()
 {
     return this;
diff --git a/libs/binder/OS.cpp b/libs/binder/OS.cpp
index 6eb7272..cc4a03b 100644
--- a/libs/binder/OS.cpp
+++ b/libs/binder/OS.cpp
@@ -48,4 +48,14 @@
     return OK;
 }
 
+status_t dupFileDescriptor(int oldFd, int* newFd) {
+    int ret = fcntl(oldFd, F_DUPFD_CLOEXEC, 0);
+    if (ret < 0) {
+        return -errno;
+    }
+
+    *newFd = ret;
+    return OK;
+}
+
 } // namespace android
diff --git a/libs/binder/OS.h b/libs/binder/OS.h
index e802e9c..d6e1c78 100644
--- a/libs/binder/OS.h
+++ b/libs/binder/OS.h
@@ -28,4 +28,6 @@
 
 status_t getRandomBytes(uint8_t* data, size_t size);
 
+status_t dupFileDescriptor(int oldFd, int* newFd);
+
 } // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 8b5d118..8887572 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -48,6 +48,7 @@
 #include <utils/String8.h>
 #include <utils/misc.h>
 
+#include "OS.h"
 #include "RpcState.h"
 #include "Static.h"
 #include "Utils.h"
@@ -1477,9 +1478,9 @@
 
 status_t Parcel::writeDupFileDescriptor(int fd)
 {
-    int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-    if (dupFd < 0) {
-        return -errno;
+    int dupFd;
+    if (status_t err = dupFileDescriptor(fd, &dupFd); err != OK) {
+        return err;
     }
     status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
     if (err != OK) {
@@ -1496,9 +1497,9 @@
 
 status_t Parcel::writeDupParcelFileDescriptor(int fd)
 {
-    int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-    if (dupFd < 0) {
-        return -errno;
+    int dupFd;
+    if (status_t err = dupFileDescriptor(fd, &dupFd); err != OK) {
+        return err;
     }
     status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
     if (err != OK) {
@@ -2295,7 +2296,12 @@
         return BAD_TYPE;
     }
 
-    val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
+    int dupFd;
+    if (status_t err = dupFileDescriptor(got, &dupFd); err != OK) {
+        return BAD_VALUE;
+    }
+
+    val->reset(dupFd);
 
     if (val->get() < 0) {
         return BAD_VALUE;
@@ -2312,7 +2318,12 @@
         return BAD_TYPE;
     }
 
-    val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
+    int dupFd;
+    if (status_t err = dupFileDescriptor(got, &dupFd); err != OK) {
+        return BAD_VALUE;
+    }
+
+    val->reset(dupFd);
 
     if (val->get() < 0) {
         return BAD_VALUE;
diff --git a/libs/binder/RpcTransportTipcAndroid.cpp b/libs/binder/RpcTransportTipcAndroid.cpp
new file mode 100644
index 0000000..79983f4
--- /dev/null
+++ b/libs/binder/RpcTransportTipcAndroid.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RpcTransportTipcAndroid"
+
+#include <binder/RpcSession.h>
+#include <binder/RpcTransportTipcAndroid.h>
+#include <log/log.h>
+#include <poll.h>
+#include <trusty/tipc.h>
+
+#include "FdTrigger.h"
+#include "RpcState.h"
+#include "RpcTransportUtils.h"
+
+using android::base::Error;
+using android::base::Result;
+
+namespace android {
+
+namespace {
+
+// RpcTransport for writing Trusty IPC clients in Android.
+class RpcTransportTipcAndroid : public RpcTransport {
+public:
+    explicit RpcTransportTipcAndroid(android::base::unique_fd socket)
+          : mSocket(std::move(socket)) {}
+
+    status_t pollRead() override {
+        if (mReadBufferPos < mReadBufferSize) {
+            // We have more data in the read buffer
+            return OK;
+        }
+
+        // Trusty IPC device is not a socket, so MSG_PEEK is not available
+        pollfd pfd{.fd = mSocket.get(), .events = static_cast<int16_t>(POLLIN), .revents = 0};
+        ssize_t ret = TEMP_FAILURE_RETRY(::poll(&pfd, 1, 0));
+        if (ret < 0) {
+            int savedErrno = errno;
+            if (savedErrno == EAGAIN || savedErrno == EWOULDBLOCK) {
+                return WOULD_BLOCK;
+            }
+
+            LOG_RPC_DETAIL("RpcTransport poll(): %s", strerror(savedErrno));
+            return -savedErrno;
+        }
+
+        if (pfd.revents & POLLNVAL) {
+            return BAD_VALUE;
+        }
+        if (pfd.revents & POLLERR) {
+            return DEAD_OBJECT;
+        }
+        if (pfd.revents & POLLHUP) {
+            return DEAD_OBJECT;
+        }
+        if (pfd.revents & POLLIN) {
+            return OK;
+        }
+
+        return WOULD_BLOCK;
+    }
+
+    status_t interruptableWriteFully(
+            FdTrigger* fdTrigger, iovec* iovs, int niovs,
+            const std::optional<android::base::function_ref<status_t()>>& altPoll,
+            const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds)
+            override {
+        auto writeFn = [&](iovec* iovs, size_t niovs) -> ssize_t {
+            // TODO: send ancillaryFds. For now, we just abort if anyone tries
+            // to send any.
+            LOG_ALWAYS_FATAL_IF(ancillaryFds != nullptr && !ancillaryFds->empty(),
+                                "File descriptors are not supported on Trusty yet");
+            return TEMP_FAILURE_RETRY(tipc_send(mSocket.get(), iovs, niovs, nullptr, 0));
+        };
+        return interruptableReadOrWrite(mSocket.get(), fdTrigger, iovs, niovs, writeFn, "tipc_send",
+                                        POLLOUT, altPoll);
+    }
+
+    status_t interruptableReadFully(
+            FdTrigger* fdTrigger, iovec* iovs, int niovs,
+            const std::optional<android::base::function_ref<status_t()>>& altPoll,
+            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /*ancillaryFds*/)
+            override {
+        auto readFn = [&](iovec* iovs, size_t niovs) -> ssize_t {
+            // Fill the read buffer at most once per readFn call, then try to
+            // return as much of it as possible. If the input iovecs are spread
+            // across multiple messages that require multiple fillReadBuffer
+            // calls, we expect the caller to advance the iovecs past the first
+            // read and call readFn as many times as needed to get all the data
+            status_t ret = fillReadBuffer();
+            if (ret != OK) {
+                return ret;
+            }
+
+            ssize_t processSize = 0;
+            for (size_t i = 0; i < niovs && mReadBufferPos < mReadBufferSize; i++) {
+                auto& iov = iovs[i];
+                size_t numBytes = std::min(iov.iov_len, mReadBufferSize - mReadBufferPos);
+                memcpy(iov.iov_base, mReadBuffer.get() + mReadBufferPos, numBytes);
+                mReadBufferPos += numBytes;
+                processSize += numBytes;
+            }
+
+            return processSize;
+        };
+        return interruptableReadOrWrite(mSocket.get(), fdTrigger, iovs, niovs, readFn, "read",
+                                        POLLIN, altPoll);
+    }
+
+private:
+    status_t fillReadBuffer() {
+        if (mReadBufferPos < mReadBufferSize) {
+            return OK;
+        }
+
+        if (!mReadBuffer) {
+            // Guarantee at least kDefaultBufferSize bytes
+            mReadBufferCapacity = std::max(mReadBufferCapacity, kDefaultBufferSize);
+            mReadBuffer.reset(new (std::nothrow) uint8_t[mReadBufferCapacity]);
+            if (!mReadBuffer) {
+                return NO_MEMORY;
+            }
+        }
+
+        // Reset the size and position in case we have to exit with an error.
+        // After we read a message into the buffer, we update the size
+        // with the actual value.
+        mReadBufferPos = 0;
+        mReadBufferSize = 0;
+
+        while (true) {
+            ssize_t processSize =
+                    TEMP_FAILURE_RETRY(read(mSocket.get(), mReadBuffer.get(), mReadBufferCapacity));
+            if (processSize == 0) {
+                return DEAD_OBJECT;
+            } else if (processSize < 0) {
+                int savedErrno = errno;
+                if (savedErrno == EMSGSIZE) {
+                    // Buffer was too small, double it and retry
+                    if (__builtin_mul_overflow(mReadBufferCapacity, 2, &mReadBufferCapacity)) {
+                        return NO_MEMORY;
+                    }
+                    mReadBuffer.reset(new (std::nothrow) uint8_t[mReadBufferCapacity]);
+                    if (!mReadBuffer) {
+                        return NO_MEMORY;
+                    }
+                    continue;
+                } else {
+                    LOG_RPC_DETAIL("RpcTransport fillBuffer(): %s", strerror(savedErrno));
+                    return -savedErrno;
+                }
+            } else {
+                mReadBufferSize = static_cast<size_t>(processSize);
+                return OK;
+            }
+        }
+    }
+
+    base::unique_fd mSocket;
+
+    // For now, we copy all the input data into a temporary buffer because
+    // we might get multiple interruptableReadFully calls per message, but
+    // the tipc device only allows one read call. We read every message into
+    // this temporary buffer, then return pieces of it from our method.
+    //
+    // The special transaction GET_MAX_THREADS takes 40 bytes, so the default
+    // size should start pretty high.
+    static constexpr size_t kDefaultBufferSize = 64;
+    std::unique_ptr<uint8_t[]> mReadBuffer;
+    size_t mReadBufferPos = 0;
+    size_t mReadBufferSize = 0;
+    size_t mReadBufferCapacity = 0;
+};
+
+// RpcTransportCtx for Trusty.
+class RpcTransportCtxTipcAndroid : public RpcTransportCtx {
+public:
+    std::unique_ptr<RpcTransport> newTransport(android::base::unique_fd fd,
+                                               FdTrigger*) const override {
+        return std::make_unique<RpcTransportTipcAndroid>(std::move(fd));
+    }
+    std::vector<uint8_t> getCertificate(RpcCertificateFormat) const override { return {}; }
+};
+
+} // namespace
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTipcAndroid::newServerCtx() const {
+    return std::make_unique<RpcTransportCtxTipcAndroid>();
+}
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTipcAndroid::newClientCtx() const {
+    return std::make_unique<RpcTransportCtxTipcAndroid>();
+}
+
+const char* RpcTransportCtxFactoryTipcAndroid::toCString() const {
+    return "trusty";
+}
+
+std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryTipcAndroid::make() {
+    return std::unique_ptr<RpcTransportCtxFactoryTipcAndroid>(
+            new RpcTransportCtxFactoryTipcAndroid());
+}
+
+} // namespace android
diff --git a/libs/binder/RpcTrusty.cpp b/libs/binder/RpcTrusty.cpp
new file mode 100644
index 0000000..ea49eef
--- /dev/null
+++ b/libs/binder/RpcTrusty.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RpcTrusty"
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <binder/RpcSession.h>
+#include <binder/RpcTransportTipcAndroid.h>
+#include <trusty/tipc.h>
+
+namespace android {
+
+using android::base::unique_fd;
+
+sp<IBinder> RpcTrustyConnect(const char* device, const char* port) {
+    auto session = RpcSession::make(RpcTransportCtxFactoryTipcAndroid::make());
+    auto request = [=] {
+        int tipcFd = tipc_connect(device, port);
+        if (tipcFd < 0) {
+            LOG(ERROR) << "Failed to connect to Trusty service. Error code: " << tipcFd;
+            return unique_fd();
+        }
+        return unique_fd(tipcFd);
+    };
+    if (status_t status = session->setupPreconnectedClient(unique_fd{}, request); status != OK) {
+        LOG(ERROR) << "Failed to set up Trusty client. Error: " << statusToString(status).c_str();
+        return nullptr;
+    }
+    return session->getRootObject();
+}
+
+} // namespace android
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 46223bb..88d9ca1 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -59,6 +59,8 @@
     virtual void*       findObject(const void* objectID) const final;
     virtual void* detachObject(const void* objectID) final;
     void withLock(const std::function<void()>& doWithLock);
+    sp<IBinder> lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make,
+                                   const void* makeArgs);
 
     virtual BBinder*    localBinder();
 
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 19ad5e6..4172cc5 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -72,6 +72,8 @@
     virtual void*       findObject(const void* objectID) const final;
     virtual void* detachObject(const void* objectID) final;
     void withLock(const std::function<void()>& doWithLock);
+    sp<IBinder> lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make,
+                                   const void* makeArgs);
 
     virtual BpBinder*   remoteBinder();
 
@@ -96,6 +98,8 @@
                      IBinder::object_cleanup_func func);
         void* find(const void* objectID) const;
         void* detach(const void* objectID);
+        sp<IBinder> lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make,
+                                       const void* makeArgs);
 
         void kill();
 
@@ -104,9 +108,9 @@
         ObjectManager& operator=(const ObjectManager&);
 
         struct entry_t {
-            void* object;
-            void* cleanupCookie;
-            IBinder::object_cleanup_func func;
+            void* object = nullptr;
+            void* cleanupCookie = nullptr;
+            IBinder::object_cleanup_func func = nullptr;
         };
 
         std::map<const void*, entry_t> mObjects;
diff --git a/libs/binder/include/binder/Delegate.h b/libs/binder/include/binder/Delegate.h
new file mode 100644
index 0000000..8b3fc1c
--- /dev/null
+++ b/libs/binder/include/binder/Delegate.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/IBinder.h>
+
+#ifndef __BIONIC__
+#ifndef __assert
+
+// defined differently by liblog
+#pragma push_macro("LOG_PRI")
+#ifdef LOG_PRI
+#undef LOG_PRI
+#endif
+#include <syslog.h>
+#pragma pop_macro("LOG_PRI")
+
+#define __assert(a, b, c)          \
+    do {                           \
+        syslog(LOG_ERR, a ": " c); \
+        abort();                   \
+    } while (false)
+#endif // __assert
+#endif // __BIONIC__
+
+namespace android {
+
+/*
+ * Used to manage AIDL's *Delegator types.
+ * This is used to:
+ * - create a new *Delegator object that delegates to the binder argument.
+ * - or return an existing *Delegator object that already delegates to the
+ * binder argument.
+ * - or return the underlying delegate binder if the binder argument is a
+ * *Delegator itself.
+ *
+ * @param binder - the binder to delegate to or unwrap
+ *
+ * @return pointer to the *Delegator object or the unwrapped binder object
+ */
+template <typename T>
+sp<T> delegate(const sp<T>& binder) {
+    const void* isDelegatorId = &T::descriptor;
+    const void* hasDelegatorId = &T::descriptor + 1;
+    // is binder itself a delegator?
+    if (T::asBinder(binder)->findObject(isDelegatorId)) {
+        if (T::asBinder(binder)->findObject(hasDelegatorId)) {
+            __assert(__FILE__, __LINE__,
+                     "This binder has a delegator and is also delegator itself! This is "
+                     "likely an unintended mixing of binders.");
+            return nullptr;
+        }
+        // unwrap the delegator
+        return static_cast<typename T::DefaultDelegator*>(binder.get())->getImpl();
+    }
+
+    struct MakeArgs {
+        const sp<T>* binder;
+        const void* id;
+    } makeArgs;
+    makeArgs.binder = &binder;
+    makeArgs.id = isDelegatorId;
+
+    // the binder is not a delegator, so construct one
+    sp<IBinder> newDelegator = T::asBinder(binder)->lookupOrCreateWeak(
+            hasDelegatorId,
+            [](const void* args) -> sp<IBinder> {
+                auto delegator = sp<typename T::DefaultDelegator>::make(
+                        *static_cast<const MakeArgs*>(args)->binder);
+                // make sure we know this binder is a delegator by attaching a unique ID
+                (void)delegator->attachObject(static_cast<const MakeArgs*>(args)->id,
+                                              reinterpret_cast<void*>(0x1), nullptr, nullptr);
+                return delegator;
+            },
+            static_cast<const void*>(&makeArgs));
+    return sp<typename T::DefaultDelegator>::cast(newDelegator);
+}
+
+} // namespace android
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 43fc5ff..83aaca7 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -284,6 +284,9 @@
 
     virtual BBinder*        localBinder();
     virtual BpBinder*       remoteBinder();
+    typedef sp<IBinder> (*object_make_func)(const void* makeArgs);
+    sp<IBinder> lookupOrCreateWeak(const void* objectID, object_make_func make,
+                                   const void* makeArgs);
 
 protected:
     virtual          ~IBinder();
diff --git a/libs/binder/include_trusty/binder/RpcTransportTipcAndroid.h b/libs/binder/include_trusty/binder/RpcTransportTipcAndroid.h
new file mode 100644
index 0000000..4a4172a
--- /dev/null
+++ b/libs/binder/include_trusty/binder/RpcTransportTipcAndroid.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Wraps the transport layer of RPC. Implementation uses Trusty IPC.
+
+#pragma once
+
+#include <memory>
+
+#include <binder/RpcTransport.h>
+
+namespace android {
+
+// RpcTransportCtxFactory for writing Trusty IPC clients in Android.
+class RpcTransportCtxFactoryTipcAndroid : public RpcTransportCtxFactory {
+public:
+    static std::unique_ptr<RpcTransportCtxFactory> make();
+
+    std::unique_ptr<RpcTransportCtx> newServerCtx() const override;
+    std::unique_ptr<RpcTransportCtx> newClientCtx() const override;
+    const char* toCString() const override;
+
+private:
+    RpcTransportCtxFactoryTipcAndroid() = default;
+};
+
+} // namespace android
diff --git a/libs/binder/include_trusty/binder/RpcTrusty.h b/libs/binder/include_trusty/binder/RpcTrusty.h
new file mode 100644
index 0000000..f124e0c
--- /dev/null
+++ b/libs/binder/include_trusty/binder/RpcTrusty.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/IBinder.h>
+
+namespace android {
+
+sp<IBinder> RpcTrustyConnect(const char* device, const char* port);
+
+} // namespace android
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
index f45aa76..c1f2620 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -58,6 +58,9 @@
 #endif
             AParcel_appendFrom(other.mParcel.get(), this->mParcel.get(), 0,
                                AParcel_getDataSize(other.mParcel.get()));
+        } else {
+            syslog(LOG_ERR,
+                   "sdk_version not compatible, AParcelableHolder need sdk_version >= 31!");
         }
     }
 #endif
@@ -192,6 +195,9 @@
         if (__ANDROID_API__ >= 31) {
 #endif
             AParcel_reset(mParcel.get());
+        } else {
+            syslog(LOG_ERR,
+                   "sdk_version not compatible, AParcelableHolder need sdk_version >= 31!");
         }
     }
 
@@ -201,6 +207,29 @@
     inline bool operator==(const AParcelableHolder& rhs) const { return this == &rhs; }
     inline bool operator>(const AParcelableHolder& rhs) const { return this > &rhs; }
     inline bool operator>=(const AParcelableHolder& rhs) const { return this >= &rhs; }
+#if __ANDROID_API__ >= 31
+    inline AParcelableHolder& operator=(const AParcelableHolder& rhs) {
+        // AParcelableHolder has been introduced in 31.
+#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
+        if (__builtin_available(android 31, *)) {
+#else
+        if (__ANDROID_API__ >= 31) {
+#endif
+            this->reset();
+            if (this->mStability != rhs.mStability) {
+                syslog(LOG_ERR, "AParcelableHolder stability mismatch: this %d rhs %d!",
+                       this->mStability, rhs.mStability);
+                abort();
+            }
+            AParcel_appendFrom(rhs.mParcel.get(), this->mParcel.get(), 0,
+                               AParcel_getDataSize(rhs.mParcel.get()));
+        } else {
+            syslog(LOG_ERR,
+                   "sdk_version not compatible, AParcelableHolder need sdk_version >= 31!");
+        }
+        return *this;
+    }
+#endif
 
    private:
     mutable ndk::ScopedAParcel mParcel;
diff --git a/libs/binder/tests/binderBinderUnitTest.cpp b/libs/binder/tests/binderBinderUnitTest.cpp
index ce2770f..b6aed0d 100644
--- a/libs/binder/tests/binderBinderUnitTest.cpp
+++ b/libs/binder/tests/binderBinderUnitTest.cpp
@@ -15,10 +15,11 @@
  */
 
 #include <binder/Binder.h>
-#include <binder/IBinder.h>
+#include <binder/IInterface.h>
 #include <gtest/gtest.h>
 
 using android::BBinder;
+using android::IBinder;
 using android::OK;
 using android::sp;
 
@@ -48,3 +49,49 @@
     binder->setExtension(ext);
     EXPECT_EQ(ext, binder->getExtension());
 }
+
+struct MyCookie {
+    bool* deleted;
+};
+
+class UniqueBinder : public BBinder {
+public:
+    UniqueBinder(const void* c) : cookie(reinterpret_cast<const MyCookie*>(c)) {
+        *cookie->deleted = false;
+    }
+    ~UniqueBinder() { *cookie->deleted = true; }
+    const MyCookie* cookie;
+};
+
+static sp<IBinder> make(const void* arg) {
+    return sp<UniqueBinder>::make(arg);
+}
+
+TEST(Binder, LookupOrCreateWeak) {
+    auto binder = sp<BBinder>::make();
+    bool deleted;
+    MyCookie cookie = {&deleted};
+    sp<IBinder> createdBinder = binder->lookupOrCreateWeak(kObjectId1, make, &cookie);
+    EXPECT_NE(binder, createdBinder);
+
+    sp<IBinder> lookedUpBinder = binder->lookupOrCreateWeak(kObjectId1, make, &cookie);
+    EXPECT_EQ(createdBinder, lookedUpBinder);
+    EXPECT_FALSE(deleted);
+}
+
+TEST(Binder, LookupOrCreateWeakDropSp) {
+    auto binder = sp<BBinder>::make();
+    bool deleted1 = false;
+    bool deleted2 = false;
+    MyCookie cookie1 = {&deleted1};
+    MyCookie cookie2 = {&deleted2};
+    sp<IBinder> createdBinder = binder->lookupOrCreateWeak(kObjectId1, make, &cookie1);
+    EXPECT_NE(binder, createdBinder);
+
+    createdBinder.clear();
+    EXPECT_TRUE(deleted1);
+
+    sp<IBinder> lookedUpBinder = binder->lookupOrCreateWeak(kObjectId1, make, &cookie2);
+    EXPECT_EQ(&cookie2, sp<UniqueBinder>::cast(lookedUpBinder)->cookie);
+    EXPECT_FALSE(deleted2);
+}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index e72f39c..5de08bd 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -1158,6 +1158,42 @@
     EXPECT_EQ(readValue, testValue);
 }
 
+// see ProcessState.cpp BINDER_VM_SIZE = 1MB.
+// This value is not exposed, but some code in the framework relies on being able to use
+// buffers near the cap size.
+// TODO(b/238777741): why do larger values, like 300K fail sometimes
+constexpr size_t kSizeBytesAlmostFull = 100'000;
+constexpr size_t kSizeBytesOverFull = 1'050'000;
+
+TEST_F(BinderLibTest, GargantuanVectorSent) {
+    sp<IBinder> server = addServer();
+    ASSERT_TRUE(server != nullptr);
+
+    for (size_t i = 0; i < 10; i++) {
+        // a slight variation in size is used to consider certain possible caching implementations
+        const std::vector<uint64_t> testValue((kSizeBytesAlmostFull + i) / sizeof(uint64_t), 42);
+
+        Parcel data, reply;
+        data.writeUint64Vector(testValue);
+        EXPECT_THAT(server->transact(BINDER_LIB_TEST_ECHO_VECTOR, data, &reply), StatusEq(NO_ERROR))
+                << i;
+        std::vector<uint64_t> readValue;
+        EXPECT_THAT(reply.readUint64Vector(&readValue), StatusEq(OK));
+        EXPECT_EQ(readValue, testValue);
+    }
+}
+
+TEST_F(BinderLibTest, LimitExceededVectorSent) {
+    sp<IBinder> server = addServer();
+    ASSERT_TRUE(server != nullptr);
+    const std::vector<uint64_t> testValue(kSizeBytesOverFull / sizeof(uint64_t), 42);
+
+    Parcel data, reply;
+    data.writeUint64Vector(testValue);
+    EXPECT_THAT(server->transact(BINDER_LIB_TEST_ECHO_VECTOR, data, &reply),
+                StatusEq(FAILED_TRANSACTION));
+}
+
 TEST_F(BinderLibTest, BufRejected) {
     Parcel data, reply;
     uint32_t buf;
diff --git a/libs/binder/trusty/OS.cpp b/libs/binder/trusty/OS.cpp
index 187add4..bbfa381 100644
--- a/libs/binder/trusty/OS.cpp
+++ b/libs/binder/trusty/OS.cpp
@@ -32,4 +32,9 @@
     return res == 1 ? OK : UNKNOWN_ERROR;
 }
 
+status_t dupFileDescriptor(int oldFd, int* newFd) {
+    // TODO: implement separately
+    return INVALID_OPERATION;
+}
+
 } // namespace android
diff --git a/libs/binder/trusty/rules.mk b/libs/binder/trusty/rules.mk
index 83475f5..d0d0861 100644
--- a/libs/binder/trusty/rules.mk
+++ b/libs/binder/trusty/rules.mk
@@ -36,6 +36,7 @@
 	$(LIBBINDER_DIR)/IInterface.cpp \
 	$(LIBBINDER_DIR)/IResultReceiver.cpp \
 	$(LIBBINDER_DIR)/Parcel.cpp \
+	$(LIBBINDER_DIR)/ParcelFileDescriptor.cpp \
 	$(LIBBINDER_DIR)/RpcServer.cpp \
 	$(LIBBINDER_DIR)/RpcSession.cpp \
 	$(LIBBINDER_DIR)/RpcState.cpp \
diff --git a/libs/sensor/fuzz/sensor_fuzzer/sensor_fuzzer.cpp b/libs/sensor/fuzz/sensor_fuzzer/sensor_fuzzer.cpp
index 129f430..0e110b7 100644
--- a/libs/sensor/fuzz/sensor_fuzzer/sensor_fuzzer.cpp
+++ b/libs/sensor/fuzz/sensor_fuzzer/sensor_fuzzer.cpp
@@ -26,8 +26,10 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
     FuzzedDataProvider fdp(data, size);
     struct sensor_t sensor_type;
-    sensor_type.name = fdp.ConsumeBytesAsString(MAX_STR_LEN).c_str();
-    sensor_type.vendor = fdp.ConsumeBytesAsString(MAX_STR_LEN).c_str();
+    std::string name = fdp.ConsumeBytesAsString(MAX_STR_LEN);
+    sensor_type.name = name.c_str();
+    std::string vendor = fdp.ConsumeBytesAsString(MAX_STR_LEN);
+    sensor_type.vendor = vendor.c_str();
     sensor_type.stringType = "";
     sensor_type.requiredPermission = "";
     sensor_type.version = fdp.ConsumeIntegral<int>();
diff --git a/services/vibratorservice/test/Android.bp b/services/vibratorservice/test/Android.bp
index 3294724..adba3db 100644
--- a/services/vibratorservice/test/Android.bp
+++ b/services/vibratorservice/test/Android.bp
@@ -57,4 +57,9 @@
     static_libs: [
         "libgmock",
     ],
+    // FIXME: Workaround LTO build breakage
+    // http://b/241699694
+    lto: {
+        never: true,
+    },
 }