xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/result.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 // Implementation of the sandbox2::Result class.
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include "sandboxed_api/sandbox2/result.h"
18*ec63e07aSXin Li 
19*ec63e07aSXin Li #include <sys/resource.h>
20*ec63e07aSXin Li 
21*ec63e07aSXin Li #include <cstdlib>
22*ec63e07aSXin Li #include <memory>
23*ec63e07aSXin Li #include <optional>
24*ec63e07aSXin Li #include <string>
25*ec63e07aSXin Li #include <vector>
26*ec63e07aSXin Li 
27*ec63e07aSXin Li #include "absl/status/status.h"
28*ec63e07aSXin Li #include "absl/strings/str_cat.h"
29*ec63e07aSXin Li #include "absl/strings/str_join.h"
30*ec63e07aSXin Li #include "sandboxed_api/config.h"
31*ec63e07aSXin Li #include "sandboxed_api/sandbox2/syscall.h"
32*ec63e07aSXin Li #include "sandboxed_api/sandbox2/util.h"
33*ec63e07aSXin Li 
34*ec63e07aSXin Li namespace sandbox2 {
35*ec63e07aSXin Li 
operator =(const Result & other)36*ec63e07aSXin Li Result& Result::operator=(const Result& other) {
37*ec63e07aSXin Li   final_status_ = other.final_status_;
38*ec63e07aSXin Li   reason_code_ = other.reason_code_;
39*ec63e07aSXin Li   stack_trace_ = other.stack_trace_;
40*ec63e07aSXin Li   if (other.regs_) {
41*ec63e07aSXin Li     regs_ = std::make_unique<Regs>(*other.regs_);
42*ec63e07aSXin Li   } else {
43*ec63e07aSXin Li     regs_.reset(nullptr);
44*ec63e07aSXin Li   }
45*ec63e07aSXin Li   if (other.syscall_) {
46*ec63e07aSXin Li     syscall_ = std::make_unique<Syscall>(*other.syscall_);
47*ec63e07aSXin Li   } else {
48*ec63e07aSXin Li     syscall_.reset(nullptr);
49*ec63e07aSXin Li   }
50*ec63e07aSXin Li   prog_name_ = other.prog_name_;
51*ec63e07aSXin Li   proc_maps_ = other.proc_maps_;
52*ec63e07aSXin Li   rusage_monitor_ = other.rusage_monitor_;
53*ec63e07aSXin Li   rusage_sandboxee_ = other.rusage_sandboxee_;
54*ec63e07aSXin Li   return *this;
55*ec63e07aSXin Li }
56*ec63e07aSXin Li 
GetStackTrace() const57*ec63e07aSXin Li std::string Result::GetStackTrace() const {
58*ec63e07aSXin Li   return absl::StrJoin(stack_trace_, " ");
59*ec63e07aSXin Li }
60*ec63e07aSXin Li 
ToStatus() const61*ec63e07aSXin Li absl::Status Result::ToStatus() const {
62*ec63e07aSXin Li   switch (final_status()) {
63*ec63e07aSXin Li     case OK:
64*ec63e07aSXin Li       if (reason_code() == 0) {
65*ec63e07aSXin Li         return absl::OkStatus();
66*ec63e07aSXin Li       }
67*ec63e07aSXin Li       break;
68*ec63e07aSXin Li     case TIMEOUT:
69*ec63e07aSXin Li       return absl::DeadlineExceededError(ToString());
70*ec63e07aSXin Li     default:
71*ec63e07aSXin Li       break;
72*ec63e07aSXin Li   }
73*ec63e07aSXin Li   return absl::InternalError(ToString());
74*ec63e07aSXin Li }
75*ec63e07aSXin Li 
ToString() const76*ec63e07aSXin Li std::string Result::ToString() const {
77*ec63e07aSXin Li   std::string result;
78*ec63e07aSXin Li   switch (final_status()) {
79*ec63e07aSXin Li     case sandbox2::Result::UNSET:
80*ec63e07aSXin Li       result = absl::StrCat("UNSET - Code: ", reason_code());
81*ec63e07aSXin Li       break;
82*ec63e07aSXin Li     case sandbox2::Result::OK:
83*ec63e07aSXin Li       result = absl::StrCat("OK - Exit code: ", reason_code());
84*ec63e07aSXin Li       break;
85*ec63e07aSXin Li     case sandbox2::Result::SETUP_ERROR:
86*ec63e07aSXin Li       result = absl::StrCat(
87*ec63e07aSXin Li           "SETUP_ERROR - Code: ",
88*ec63e07aSXin Li           ReasonCodeEnumToString(static_cast<ReasonCodeEnum>(reason_code())));
89*ec63e07aSXin Li       break;
90*ec63e07aSXin Li     case sandbox2::Result::VIOLATION:
91*ec63e07aSXin Li       if (syscall_) {
92*ec63e07aSXin Li         result = absl::StrCat("SYSCALL VIOLATION - Violating Syscall ",
93*ec63e07aSXin Li                               syscall_->GetDescription(),
94*ec63e07aSXin Li                               " Stack: ", GetStackTrace());
95*ec63e07aSXin Li       } else if (reason_code() == sandbox2::Result::VIOLATION_NETWORK) {
96*ec63e07aSXin Li         result = absl::StrCat("NETWORK VIOLATION: ", GetNetworkViolation());
97*ec63e07aSXin Li       } else {
98*ec63e07aSXin Li         result = "SYSCALL VIOLATION - Unknown Violation";
99*ec63e07aSXin Li       }
100*ec63e07aSXin Li       break;
101*ec63e07aSXin Li     case sandbox2::Result::SIGNALED:
102*ec63e07aSXin Li       result = absl::StrCat("Process terminated with a SIGNAL - Signal: ",
103*ec63e07aSXin Li                             util::GetSignalName(reason_code()),
104*ec63e07aSXin Li                             " Stack: ", GetStackTrace());
105*ec63e07aSXin Li       break;
106*ec63e07aSXin Li     case sandbox2::Result::TIMEOUT:
107*ec63e07aSXin Li       result = absl::StrCat("Process TIMEOUT - Code: ", reason_code(),
108*ec63e07aSXin Li                             " Stack: ", GetStackTrace());
109*ec63e07aSXin Li       break;
110*ec63e07aSXin Li     case sandbox2::Result::EXTERNAL_KILL:
111*ec63e07aSXin Li       result = absl::StrCat("Process killed by user - Code: ", reason_code(),
112*ec63e07aSXin Li                             " Stack: ", GetStackTrace());
113*ec63e07aSXin Li       break;
114*ec63e07aSXin Li     case sandbox2::Result::INTERNAL_ERROR:
115*ec63e07aSXin Li       result = absl::StrCat(
116*ec63e07aSXin Li           "INTERNAL_ERROR - Code: ",
117*ec63e07aSXin Li           ReasonCodeEnumToString(static_cast<ReasonCodeEnum>(reason_code())));
118*ec63e07aSXin Li       break;
119*ec63e07aSXin Li     default:
120*ec63e07aSXin Li       result =
121*ec63e07aSXin Li           absl::StrCat("<UNKNOWN>(", final_status(), ") Code: ", reason_code());
122*ec63e07aSXin Li   }
123*ec63e07aSXin Li   if constexpr (sapi::sanitizers::IsAny()) {
124*ec63e07aSXin Li     absl::StrAppend(
125*ec63e07aSXin Li         &result,
126*ec63e07aSXin Li         " - Warning: this executor is built with ASAN, MSAN or TSAN, chances "
127*ec63e07aSXin Li         "are the sandboxee is too, which is incompatible with sandboxing.");
128*ec63e07aSXin Li   } else {
129*ec63e07aSXin Li     if (
130*ec63e07aSXin Li         getenv("COVERAGE") != nullptr) {
131*ec63e07aSXin Li       absl::StrAppend(
132*ec63e07aSXin Li           &result,
133*ec63e07aSXin Li           " - Warning: this executor is built with coverage enabled, chances "
134*ec63e07aSXin Li           "are the sandboxee too, which is incompatible with sandboxing.");
135*ec63e07aSXin Li     }
136*ec63e07aSXin Li   }
137*ec63e07aSXin Li   return result;
138*ec63e07aSXin Li }
139*ec63e07aSXin Li 
StatusEnumToString(StatusEnum value)140*ec63e07aSXin Li std::string Result::StatusEnumToString(StatusEnum value) {
141*ec63e07aSXin Li   switch (value) {
142*ec63e07aSXin Li     case sandbox2::Result::UNSET:
143*ec63e07aSXin Li       return "UNSET";
144*ec63e07aSXin Li     case sandbox2::Result::OK:
145*ec63e07aSXin Li       return "OK";
146*ec63e07aSXin Li     case sandbox2::Result::SETUP_ERROR:
147*ec63e07aSXin Li       return "SETUP_ERROR";
148*ec63e07aSXin Li     case sandbox2::Result::VIOLATION:
149*ec63e07aSXin Li       return "VIOLATION";
150*ec63e07aSXin Li     case sandbox2::Result::SIGNALED:
151*ec63e07aSXin Li       return "SIGNALED";
152*ec63e07aSXin Li     case sandbox2::Result::TIMEOUT:
153*ec63e07aSXin Li       return "TIMEOUT";
154*ec63e07aSXin Li     case sandbox2::Result::EXTERNAL_KILL:
155*ec63e07aSXin Li       return "EXTERNAL_KILL";
156*ec63e07aSXin Li     case sandbox2::Result::INTERNAL_ERROR:
157*ec63e07aSXin Li       return "INTERNAL_ERROR";
158*ec63e07aSXin Li   }
159*ec63e07aSXin Li   return "UNKNOWN";
160*ec63e07aSXin Li }
161*ec63e07aSXin Li 
ReasonCodeEnumToString(ReasonCodeEnum value)162*ec63e07aSXin Li std::string Result::ReasonCodeEnumToString(ReasonCodeEnum value) {
163*ec63e07aSXin Li   switch (value) {
164*ec63e07aSXin Li     case sandbox2::Result::UNSUPPORTED_ARCH:
165*ec63e07aSXin Li       return "UNSUPPORTED_ARCH";
166*ec63e07aSXin Li     case sandbox2::Result::FAILED_TIMERS:
167*ec63e07aSXin Li       return "FAILED_TIMERS";
168*ec63e07aSXin Li     case sandbox2::Result::FAILED_SIGNALS:
169*ec63e07aSXin Li       return "FAILED_SIGNALS";
170*ec63e07aSXin Li     case sandbox2::Result::FAILED_SUBPROCESS:
171*ec63e07aSXin Li       return "FAILED_SUBPROCESS";
172*ec63e07aSXin Li     case sandbox2::Result::FAILED_NOTIFY:
173*ec63e07aSXin Li       return "FAILED_NOTIFY";
174*ec63e07aSXin Li     case sandbox2::Result::FAILED_CONNECTION:
175*ec63e07aSXin Li       return "FAILED_CONNECTION";
176*ec63e07aSXin Li     case sandbox2::Result::FAILED_WAIT:
177*ec63e07aSXin Li       return "FAILED_WAIT";
178*ec63e07aSXin Li     case sandbox2::Result::FAILED_NAMESPACES:
179*ec63e07aSXin Li       return "FAILED_NAMESPACES";
180*ec63e07aSXin Li     case sandbox2::Result::FAILED_PTRACE:
181*ec63e07aSXin Li       return "FAILED_PTRACE";
182*ec63e07aSXin Li     case sandbox2::Result::FAILED_IPC:
183*ec63e07aSXin Li       return "FAILED_IPC";
184*ec63e07aSXin Li     case sandbox2::Result::FAILED_LIMITS:
185*ec63e07aSXin Li       return "FAILED_LIMITS";
186*ec63e07aSXin Li     case sandbox2::Result::FAILED_CWD:
187*ec63e07aSXin Li       return "FAILED_CWD";
188*ec63e07aSXin Li     case sandbox2::Result::FAILED_POLICY:
189*ec63e07aSXin Li       return "FAILED_POLICY";
190*ec63e07aSXin Li     case sandbox2::Result::FAILED_STORE:
191*ec63e07aSXin Li       return "FAILED_STORE";
192*ec63e07aSXin Li     case sandbox2::Result::FAILED_FETCH:
193*ec63e07aSXin Li       return "FAILED_FETCH";
194*ec63e07aSXin Li     case sandbox2::Result::FAILED_GETEVENT:
195*ec63e07aSXin Li       return "FAILED_GETEVENT";
196*ec63e07aSXin Li     case sandbox2::Result::FAILED_MONITOR:
197*ec63e07aSXin Li       return "FAILED_MONITOR";
198*ec63e07aSXin Li     case sandbox2::Result::FAILED_KILL:
199*ec63e07aSXin Li       return "FAILED_KILL";
200*ec63e07aSXin Li     case sandbox2::Result::FAILED_INTERRUPT:
201*ec63e07aSXin Li       return "FAILED_INTERRUPT";
202*ec63e07aSXin Li     case sandbox2::Result::FAILED_CHILD:
203*ec63e07aSXin Li       return "FAILED_CHILD";
204*ec63e07aSXin Li     case sandbox2::Result::FAILED_INSPECT:
205*ec63e07aSXin Li       return "FAILED_INSPECT";
206*ec63e07aSXin Li     case sandbox2::Result::VIOLATION_SYSCALL:
207*ec63e07aSXin Li       return "VIOLATION_SYSCALL";
208*ec63e07aSXin Li     case sandbox2::Result::VIOLATION_ARCH:
209*ec63e07aSXin Li       return "VIOLATION_ARCH";
210*ec63e07aSXin Li     case sandbox2::Result::VIOLATION_NETWORK:
211*ec63e07aSXin Li       return "VIOLATION_NETWORK";
212*ec63e07aSXin Li   }
213*ec63e07aSXin Li   return absl::StrCat("UNKNOWN: ", value);
214*ec63e07aSXin Li }
215*ec63e07aSXin Li 
216*ec63e07aSXin Li }  // namespace sandbox2
217