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