2121#include < log/log.h>
2222#include < poll.h>
2323#include < trusty/tipc.h>
24+ #include < type_traits>
2425
2526#include " FdTrigger.h"
2627#include " RpcState.h"
@@ -32,6 +33,9 @@ using android::binder::unique_fd;
3233
3334namespace android {
3435
36+ // Corresponds to IPC_MAX_MSG_HANDLES in the Trusty kernel
37+ constexpr size_t kMaxTipcHandles = 8 ;
38+
3539// RpcTransport for writing Trusty IPC clients in Android.
3640class RpcTransportTipcAndroid : public RpcTransport {
3741public:
@@ -78,12 +82,28 @@ class RpcTransportTipcAndroid : public RpcTransport {
7882 FdTrigger* fdTrigger, iovec* iovs, int niovs,
7983 const std::optional<SmallFunction<status_t ()>>& altPoll,
8084 const std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) override {
85+ bool sentFds = false ;
8186 auto writeFn = [&](iovec* iovs, size_t niovs) -> ssize_t {
82- // TODO: send ancillaryFds. For now, we just abort if anyone tries
83- // to send any.
84- LOG_ALWAYS_FATAL_IF (ancillaryFds != nullptr && !ancillaryFds->empty (),
85- " File descriptors are not supported on Trusty yet" );
86- return TEMP_FAILURE_RETRY (tipc_send (mSocket .fd .get (), iovs, niovs, nullptr , 0 ));
87+ trusty_shm shms[kMaxTipcHandles ] = {{0 }};
88+ ssize_t shm_count = 0 ;
89+
90+ if (!sentFds && ancillaryFds != nullptr && !ancillaryFds->empty ()) {
91+ if (ancillaryFds->size () > kMaxTipcHandles ) {
92+ ALOGE (" Too many file descriptors for TIPC: %zu" , ancillaryFds->size ());
93+ errno = EINVAL;
94+ return -1 ;
95+ }
96+ for (const auto & fdVariant : *ancillaryFds) {
97+ shms[shm_count++] = {std::visit ([](const auto & fd) { return fd.get (); },
98+ fdVariant),
99+ TRUSTY_SEND_SECURE_OR_SHARE};
100+ }
101+ }
102+
103+ auto ret = TEMP_FAILURE_RETRY (tipc_send (mSocket .fd .get (), iovs, niovs,
104+ (shm_count == 0 ) ? nullptr : shms, shm_count));
105+ sentFds |= ret >= 0 ;
106+ return ret;
87107 };
88108
89109 status_t status = interruptableReadOrWrite (mSocket , fdTrigger, iovs, niovs, writeFn,
0 commit comments