xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/rpcchannel.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li // Copyright 2019 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li //     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li 
15*ec63e07aSXin Li #include "sandboxed_api/rpcchannel.h"
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <cstdint>
18*ec63e07aSXin Li #include <cstring>
19*ec63e07aSXin Li #include <string>
20*ec63e07aSXin Li 
21*ec63e07aSXin Li #include "absl/log/log.h"
22*ec63e07aSXin Li #include "absl/status/status.h"
23*ec63e07aSXin Li #include "absl/status/statusor.h"
24*ec63e07aSXin Li #include "absl/strings/str_cat.h"
25*ec63e07aSXin Li #include "absl/synchronization/mutex.h"
26*ec63e07aSXin Li #include "sandboxed_api/call.h"
27*ec63e07aSXin Li #include "sandboxed_api/sandbox2/comms.h"
28*ec63e07aSXin Li #include "sandboxed_api/util/raw_logging.h"
29*ec63e07aSXin Li #include "sandboxed_api/util/status_macros.h"
30*ec63e07aSXin Li 
31*ec63e07aSXin Li namespace sapi {
32*ec63e07aSXin Li 
Call(const FuncCall & call,uint32_t tag,FuncRet * ret,v::Type exp_type)33*ec63e07aSXin Li absl::Status RPCChannel::Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
34*ec63e07aSXin Li                               v::Type exp_type) {
35*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
36*ec63e07aSXin Li   if (!comms_->SendTLV(tag, sizeof(call), &call)) {
37*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
38*ec63e07aSXin Li   }
39*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(exp_type));
40*ec63e07aSXin Li   *ret = fret;
41*ec63e07aSXin Li   return absl::OkStatus();
42*ec63e07aSXin Li }
43*ec63e07aSXin Li 
Return(v::Type exp_type)44*ec63e07aSXin Li absl::StatusOr<FuncRet> RPCChannel::Return(v::Type exp_type) {
45*ec63e07aSXin Li   uint32_t tag;
46*ec63e07aSXin Li   size_t len;
47*ec63e07aSXin Li   FuncRet ret;
48*ec63e07aSXin Li   if (!comms_->RecvTLV(&tag, &len, &ret, sizeof(ret))) {
49*ec63e07aSXin Li     return absl::UnavailableError("Receiving TLV value failed");
50*ec63e07aSXin Li   }
51*ec63e07aSXin Li   if (tag != comms::kMsgReturn) {
52*ec63e07aSXin Li     LOG(ERROR) << "tag != comms::kMsgReturn (" << absl::StrCat(absl::Hex(tag))
53*ec63e07aSXin Li                << " != " << absl::StrCat(absl::Hex(comms::kMsgReturn)) << ")";
54*ec63e07aSXin Li     return absl::UnavailableError("Received TLV has incorrect tag");
55*ec63e07aSXin Li   }
56*ec63e07aSXin Li   if (len != sizeof(FuncRet)) {
57*ec63e07aSXin Li     LOG(ERROR) << "len != sizeof(FuncReturn) (" << len
58*ec63e07aSXin Li                << " != " << sizeof(FuncRet) << ")";
59*ec63e07aSXin Li     return absl::UnavailableError("Received TLV has incorrect length");
60*ec63e07aSXin Li   }
61*ec63e07aSXin Li   if (ret.ret_type != exp_type) {
62*ec63e07aSXin Li     LOG(ERROR) << "FuncRet->type != exp_type (" << ret.ret_type
63*ec63e07aSXin Li                << " != " << exp_type << ")";
64*ec63e07aSXin Li     return absl::UnavailableError("Received TLV has incorrect return type");
65*ec63e07aSXin Li   }
66*ec63e07aSXin Li   if (!ret.success) {
67*ec63e07aSXin Li     LOG(ERROR) << "FuncRet->success == false";
68*ec63e07aSXin Li     return absl::UnavailableError("Function call failed");
69*ec63e07aSXin Li   }
70*ec63e07aSXin Li   return ret;
71*ec63e07aSXin Li }
72*ec63e07aSXin Li 
Allocate(size_t size,void ** addr)73*ec63e07aSXin Li absl::Status RPCChannel::Allocate(size_t size, void** addr) {
74*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
75*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgAllocate, sizeof(size), &size)) {
76*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
77*ec63e07aSXin Li   }
78*ec63e07aSXin Li 
79*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
80*ec63e07aSXin Li   *addr = reinterpret_cast<void*>(fret.int_val);
81*ec63e07aSXin Li   return absl::OkStatus();
82*ec63e07aSXin Li }
83*ec63e07aSXin Li 
Reallocate(void * old_addr,size_t size,void ** new_addr)84*ec63e07aSXin Li absl::Status RPCChannel::Reallocate(void* old_addr, size_t size,
85*ec63e07aSXin Li                                     void** new_addr) {
86*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
87*ec63e07aSXin Li   comms::ReallocRequest req = {
88*ec63e07aSXin Li       .old_addr = reinterpret_cast<uintptr_t>(old_addr),
89*ec63e07aSXin Li       .size = size,
90*ec63e07aSXin Li   };
91*ec63e07aSXin Li 
92*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgReallocate, sizeof(comms::ReallocRequest),
93*ec63e07aSXin Li                        &req)) {
94*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
95*ec63e07aSXin Li   }
96*ec63e07aSXin Li 
97*ec63e07aSXin Li   auto fret_or = Return(v::Type::kPointer);
98*ec63e07aSXin Li   if (!fret_or.ok()) {
99*ec63e07aSXin Li     *new_addr = nullptr;
100*ec63e07aSXin Li     return absl::UnavailableError(
101*ec63e07aSXin Li         absl::StrCat("Reallocate() failed on the remote side: ",
102*ec63e07aSXin Li                      fret_or.status().message()));
103*ec63e07aSXin Li   }
104*ec63e07aSXin Li   *new_addr = reinterpret_cast<void*>(fret_or->int_val);
105*ec63e07aSXin Li   return absl::OkStatus();
106*ec63e07aSXin Li }
107*ec63e07aSXin Li 
Free(void * addr)108*ec63e07aSXin Li absl::Status RPCChannel::Free(void* addr) {
109*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
110*ec63e07aSXin Li   uintptr_t remote = reinterpret_cast<uintptr_t>(addr);
111*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgFree, sizeof(remote), &remote)) {
112*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
113*ec63e07aSXin Li   }
114*ec63e07aSXin Li 
115*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
116*ec63e07aSXin Li   if (!fret.success) {
117*ec63e07aSXin Li     return absl::UnavailableError("Free() failed on the remote side");
118*ec63e07aSXin Li   }
119*ec63e07aSXin Li   return absl::OkStatus();
120*ec63e07aSXin Li }
121*ec63e07aSXin Li 
Symbol(const char * symname,void ** addr)122*ec63e07aSXin Li absl::Status RPCChannel::Symbol(const char* symname, void** addr) {
123*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
124*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgSymbol, strlen(symname) + 1, symname)) {
125*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
126*ec63e07aSXin Li   }
127*ec63e07aSXin Li 
128*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
129*ec63e07aSXin Li   *addr = reinterpret_cast<void*>(fret.int_val);
130*ec63e07aSXin Li   return absl::OkStatus();
131*ec63e07aSXin Li }
132*ec63e07aSXin Li 
Exit()133*ec63e07aSXin Li absl::Status RPCChannel::Exit() {
134*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
135*ec63e07aSXin Li   if (comms_->IsTerminated()) {
136*ec63e07aSXin Li     VLOG(2) << "Comms channel already terminated";
137*ec63e07aSXin Li     return absl::OkStatus();
138*ec63e07aSXin Li   }
139*ec63e07aSXin Li 
140*ec63e07aSXin Li   // Try the RPC exit sequence. But, the only thing that matters as a success
141*ec63e07aSXin Li   // indicator is whether the Comms channel had been closed
142*ec63e07aSXin Li   comms_->SendTLV(comms::kMsgExit, 0, nullptr);
143*ec63e07aSXin Li   return absl::OkStatus();
144*ec63e07aSXin Li }
145*ec63e07aSXin Li 
SendFD(int local_fd,int * remote_fd)146*ec63e07aSXin Li absl::Status RPCChannel::SendFD(int local_fd, int* remote_fd) {
147*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
148*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgSendFd, 0, nullptr)) {
149*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
150*ec63e07aSXin Li   }
151*ec63e07aSXin Li   if (!comms_->SendFD(local_fd)) {
152*ec63e07aSXin Li     return absl::UnavailableError("Sending FD failed");
153*ec63e07aSXin Li   }
154*ec63e07aSXin Li 
155*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kInt));
156*ec63e07aSXin Li   if (!fret.success) {
157*ec63e07aSXin Li     return absl::UnavailableError("SendFD failed on the remote side");
158*ec63e07aSXin Li   }
159*ec63e07aSXin Li   *remote_fd = fret.int_val;
160*ec63e07aSXin Li   return absl::OkStatus();
161*ec63e07aSXin Li }
162*ec63e07aSXin Li 
RecvFD(int remote_fd,int * local_fd)163*ec63e07aSXin Li absl::Status RPCChannel::RecvFD(int remote_fd, int* local_fd) {
164*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
165*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgRecvFd, sizeof(remote_fd), &remote_fd)) {
166*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
167*ec63e07aSXin Li   }
168*ec63e07aSXin Li 
169*ec63e07aSXin Li   if (!comms_->RecvFD(local_fd)) {
170*ec63e07aSXin Li     return absl::UnavailableError("Receving FD failed");
171*ec63e07aSXin Li   }
172*ec63e07aSXin Li 
173*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
174*ec63e07aSXin Li   if (!fret.success) {
175*ec63e07aSXin Li     return absl::UnavailableError("RecvFD failed on the remote side");
176*ec63e07aSXin Li   }
177*ec63e07aSXin Li   return absl::OkStatus();
178*ec63e07aSXin Li }
179*ec63e07aSXin Li 
Close(int remote_fd)180*ec63e07aSXin Li absl::Status RPCChannel::Close(int remote_fd) {
181*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
182*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgClose, sizeof(remote_fd), &remote_fd)) {
183*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
184*ec63e07aSXin Li   }
185*ec63e07aSXin Li 
186*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
187*ec63e07aSXin Li   if (!fret.success) {
188*ec63e07aSXin Li     return absl::UnavailableError("Close() failed on the remote side");
189*ec63e07aSXin Li   }
190*ec63e07aSXin Li   return absl::OkStatus();
191*ec63e07aSXin Li }
192*ec63e07aSXin Li 
Strlen(void * str)193*ec63e07aSXin Li absl::StatusOr<size_t> RPCChannel::Strlen(void* str) {
194*ec63e07aSXin Li   absl::MutexLock lock(&mutex_);
195*ec63e07aSXin Li   if (!comms_->SendTLV(comms::kMsgStrlen, sizeof(str), &str)) {
196*ec63e07aSXin Li     return absl::UnavailableError("Sending TLV value failed");
197*ec63e07aSXin Li   }
198*ec63e07aSXin Li 
199*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kInt));
200*ec63e07aSXin Li   if (!fret.success) {
201*ec63e07aSXin Li     return absl::UnavailableError("Close() failed on the remote side");
202*ec63e07aSXin Li   }
203*ec63e07aSXin Li   return fret.int_val;
204*ec63e07aSXin Li }
205*ec63e07aSXin Li 
206*ec63e07aSXin Li }  // namespace sapi
207