xref: /aosp_15_r20/frameworks/native/libs/binder/trusty/include/binder/RpcServerTrusty.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <binder/ARpcServerTrusty.h>
20 #include <binder/IBinder.h>
21 #include <binder/RpcServer.h>
22 #include <binder/RpcSession.h>
23 #include <binder/RpcTransport.h>
24 #include <binder/unique_fd.h>
25 #include <utils/Errors.h>
26 #include <utils/RefBase.h>
27 
28 #include <map>
29 #include <vector>
30 
31 #include <lib/tipc/tipc_srv.h>
32 
33 namespace android {
34 
35 /**
36  * This is the Trusty-specific RPC server code.
37  */
38 class RpcServerTrusty final : public virtual RefBase {
39 public:
40     // C++ equivalent to tipc_port_acl that uses safe data structures instead of
41     // raw pointers, except for |extraData| which doesn't have a good
42     // equivalent.
43     struct PortAcl {
44         uint32_t flags;
45         std::vector<uuid> uuids;
46         const void* extraData;
47     };
48 
49     /**
50      * Creates an RPC server listening on the given port and adds it to the
51      * Trusty handle set at |handleSet|.
52      *
53      * The caller is responsible for calling tipc_run_event_loop() to start
54      * the TIPC event loop after creating one or more services here.
55      */
56     static sp<RpcServerTrusty> make(
57             tipc_hset* handleSet, std::string&& portName, std::shared_ptr<const PortAcl>&& portAcl,
58             size_t msgMaxSize,
59             std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory = nullptr);
60 
setProtocolVersion(uint32_t version)61     [[nodiscard]] bool setProtocolVersion(uint32_t version) {
62         return mRpcServer->setProtocolVersion(version);
63     }
setSupportedFileDescriptorTransportModes(const std::vector<RpcSession::FileDescriptorTransportMode> & modes)64     void setSupportedFileDescriptorTransportModes(
65             const std::vector<RpcSession::FileDescriptorTransportMode>& modes) {
66         mRpcServer->setSupportedFileDescriptorTransportModes(modes);
67     }
setRootObject(const sp<IBinder> & binder)68     void setRootObject(const sp<IBinder>& binder) { mRpcServer->setRootObject(binder); }
setRootObjectWeak(const wp<IBinder> & binder)69     void setRootObjectWeak(const wp<IBinder>& binder) { mRpcServer->setRootObjectWeak(binder); }
setPerSessionRootObject(std::function<sp<IBinder> (wp<RpcSession> session,const void *,size_t)> && object)70     void setPerSessionRootObject(
71             std::function<sp<IBinder>(wp<RpcSession> session, const void*, size_t)>&& object) {
72         mRpcServer->setPerSessionRootObject(std::move(object));
73     }
getRootObject()74     sp<IBinder> getRootObject() { return mRpcServer->getRootObject(); }
75 
76     /**
77      * For debugging!
78      */
listSessions()79     std::vector<sp<RpcSession>> listSessions() { return mRpcServer->listSessions(); }
80 
81 private:
82     // Both this class and RpcServer have multiple non-copyable fields,
83     // including mPortAcl below which can't be copied because mUuidPtrs
84     // holds pointers into it
85     RpcServerTrusty(const RpcServerTrusty&) = delete;
86     void operator=(const RpcServerTrusty&) = delete;
87 
88     friend sp<RpcServerTrusty>;
89     explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName,
90                              std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize);
91 
92     // Internal helper that creates the RpcServer.
93     // This is used both from here and Rust.
makeRpcServer(std::unique_ptr<RpcTransportCtx> ctx)94     static sp<RpcServer> makeRpcServer(std::unique_ptr<RpcTransportCtx> ctx) {
95         auto rpcServer = sp<RpcServer>::make(std::move(ctx));
96 
97         // TODO(b/266741352): follow-up to prevent needing this in the future
98         // Trusty needs to be set to the latest stable version that is in prebuilts there.
99         LOG_ALWAYS_FATAL_IF(!rpcServer->setProtocolVersion(0));
100 
101         return rpcServer;
102     }
103 
104     friend struct ::ARpcServerTrusty;
105     friend ::ARpcServerTrusty* ::ARpcServerTrusty_newPerSession(::AIBinder* (*)(const void*, size_t,
106                                                                                 char*),
107                                                                 char*, void (*)(char*));
108     friend void ::ARpcServerTrusty_delete(::ARpcServerTrusty*);
109     friend int ::ARpcServerTrusty_handleConnect(::ARpcServerTrusty*, handle_t, const uuid*, void**);
110     friend int ::ARpcServerTrusty_handleMessage(void*);
111     friend void ::ARpcServerTrusty_handleDisconnect(void*);
112     friend void ::ARpcServerTrusty_handleChannelCleanup(void*);
113 
114     // The Rpc-specific context maintained for every open TIPC channel.
115     struct ChannelContext {
116         sp<RpcSession> session;
117         sp<RpcSession::RpcConnection> connection;
118     };
119 
120     static int handleConnect(const tipc_port* port, handle_t chan, const uuid* peer, void** ctx_p);
121     static int handleMessage(const tipc_port* port, handle_t chan, void* ctx);
122     static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx);
123     static void handleChannelCleanup(void* ctx);
124 
125     static int handleConnectInternal(RpcServer* rpcServer, handle_t chan, const uuid* peer,
126                                      void** ctx_p);
127     static int handleMessageInternal(void* ctx);
128     static void handleDisconnectInternal(void* ctx);
129 
130     static constexpr tipc_srv_ops kTipcOps = {
131             .on_connect = &handleConnect,
132             .on_message = &handleMessage,
133             .on_disconnect = &handleDisconnect,
134             .on_channel_cleanup = &handleChannelCleanup,
135     };
136 
137     sp<RpcServer> mRpcServer;
138     std::string mPortName;
139     std::shared_ptr<const PortAcl> mPortAcl;
140     std::vector<const uuid*> mUuidPtrs;
141     tipc_port_acl mTipcPortAcl;
142     tipc_port mTipcPort;
143 };
144 
145 } // namespace android
146