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