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