xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/var_int.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/var_int.h"
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <unistd.h>
18*ec63e07aSXin Li 
19*ec63e07aSXin Li #include "absl/log/log.h"
20*ec63e07aSXin Li #include "absl/status/status.h"
21*ec63e07aSXin Li #include "sandboxed_api/rpcchannel.h"
22*ec63e07aSXin Li #include "sandboxed_api/util/status_macros.h"
23*ec63e07aSXin Li 
24*ec63e07aSXin Li namespace sapi::v {
25*ec63e07aSXin Li 
~Fd()26*ec63e07aSXin Li Fd::~Fd() {
27*ec63e07aSXin Li   if (GetFreeRPCChannel() && GetRemoteFd() >= 0 && own_remote_) {
28*ec63e07aSXin Li     this->CloseRemoteFd(GetFreeRPCChannel()).IgnoreError();
29*ec63e07aSXin Li   }
30*ec63e07aSXin Li   if (GetValue() >= 0 && own_local_) {
31*ec63e07aSXin Li     CloseLocalFd();
32*ec63e07aSXin Li   }
33*ec63e07aSXin Li }
34*ec63e07aSXin Li 
CloseRemoteFd(RPCChannel * rpc_channel)35*ec63e07aSXin Li absl::Status Fd::CloseRemoteFd(RPCChannel* rpc_channel) {
36*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(rpc_channel->Close(GetRemoteFd()));
37*ec63e07aSXin Li 
38*ec63e07aSXin Li   SetRemoteFd(-1);
39*ec63e07aSXin Li   return absl::OkStatus();
40*ec63e07aSXin Li }
41*ec63e07aSXin Li 
CloseLocalFd()42*ec63e07aSXin Li void Fd::CloseLocalFd() {
43*ec63e07aSXin Li   if (GetValue() < 0) {
44*ec63e07aSXin Li     return;
45*ec63e07aSXin Li   }
46*ec63e07aSXin Li   if (close(GetValue()) != 0) {
47*ec63e07aSXin Li     PLOG(WARNING) << "close(" << GetValue() << ") failed";
48*ec63e07aSXin Li   }
49*ec63e07aSXin Li 
50*ec63e07aSXin Li   SetValue(-1);
51*ec63e07aSXin Li }
52*ec63e07aSXin Li 
TransferToSandboxee(RPCChannel * rpc_channel,pid_t)53*ec63e07aSXin Li absl::Status Fd::TransferToSandboxee(RPCChannel* rpc_channel, pid_t /* pid */) {
54*ec63e07aSXin Li   int remote_fd;
55*ec63e07aSXin Li 
56*ec63e07aSXin Li   SetFreeRPCChannel(rpc_channel);
57*ec63e07aSXin Li   OwnRemoteFd(true);
58*ec63e07aSXin Li 
59*ec63e07aSXin Li   if (GetValue() < 0) {
60*ec63e07aSXin Li     return absl::FailedPreconditionError(
61*ec63e07aSXin Li         "Cannot transfer FD: Local FD not valid");
62*ec63e07aSXin Li   }
63*ec63e07aSXin Li 
64*ec63e07aSXin Li   if (GetRemoteFd() >= 0) {
65*ec63e07aSXin Li     return absl::FailedPreconditionError(
66*ec63e07aSXin Li         "Cannot transfer FD: Sandboxee already has a valid FD");
67*ec63e07aSXin Li   }
68*ec63e07aSXin Li 
69*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(rpc_channel->SendFD(GetValue(), &remote_fd));
70*ec63e07aSXin Li   SetRemoteFd(remote_fd);
71*ec63e07aSXin Li 
72*ec63e07aSXin Li   return absl::OkStatus();
73*ec63e07aSXin Li }
74*ec63e07aSXin Li 
TransferFromSandboxee(RPCChannel * rpc_channel,pid_t)75*ec63e07aSXin Li absl::Status Fd::TransferFromSandboxee(RPCChannel* rpc_channel,
76*ec63e07aSXin Li                                        pid_t /* pid */) {
77*ec63e07aSXin Li   int local_fd;
78*ec63e07aSXin Li 
79*ec63e07aSXin Li   SetFreeRPCChannel(rpc_channel);
80*ec63e07aSXin Li   OwnRemoteFd(false);
81*ec63e07aSXin Li 
82*ec63e07aSXin Li   if (GetValue()) {
83*ec63e07aSXin Li     return absl::FailedPreconditionError(
84*ec63e07aSXin Li         "Cannot transfer FD back: Our FD is already valid");
85*ec63e07aSXin Li   }
86*ec63e07aSXin Li 
87*ec63e07aSXin Li   if (GetRemoteFd() < 0) {
88*ec63e07aSXin Li     return absl::FailedPreconditionError(
89*ec63e07aSXin Li         "Cannot transfer FD back: Sandboxee has no valid FD");
90*ec63e07aSXin Li   }
91*ec63e07aSXin Li 
92*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(rpc_channel->RecvFD(GetRemoteFd(), &local_fd));
93*ec63e07aSXin Li   SetValue(local_fd);
94*ec63e07aSXin Li 
95*ec63e07aSXin Li   return absl::OkStatus();
96*ec63e07aSXin Li }
97*ec63e07aSXin Li 
98*ec63e07aSXin Li }  // namespace sapi::v
99