mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
5eed4ec606
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
||||||
[submodule "oss-internship-2020/openjpeg/openjpeg"]
|
[submodule "oss-internship-2020/openjpeg/openjpeg"]
|
||||||
path = oss-internship-2020/openjpeg/openjpeg
|
path = oss-internship-2020/openjpeg/openjpeg
|
||||||
url = https://github.com/uclouvain/openjpeg.git
|
url = https://github.com/uclouvain/openjpeg.git
|
||||||
|
[submodule "oss-internship-2020/pffft/master"]
|
||||||
|
path = oss-internship-2020/pffft/master
|
||||||
|
url = https://bitbucket.org/jpommier/pffft/src/master/
|
|
@ -18,7 +18,7 @@ project(absl-download NONE)
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
ExternalProject_Add(absl
|
ExternalProject_Add(absl
|
||||||
GIT_REPOSITORY https://github.com/abseil/abseil-cpp
|
GIT_REPOSITORY https://github.com/abseil/abseil-cpp
|
||||||
GIT_TAG 6e18c7115df9b7ca0987cc346b1b1d4b3cc829b3 # 2020-04-28
|
GIT_TAG 0e9921b75a0fdd639a504ec8443fc1fe801becd7 # 2020-09-02
|
||||||
SOURCE_DIR "${CMAKE_BINARY_DIR}/absl-src"
|
SOURCE_DIR "${CMAKE_BINARY_DIR}/absl-src"
|
||||||
BINARY_DIR "${CMAKE_BINARY_DIR}/absl-build"
|
BINARY_DIR "${CMAKE_BINARY_DIR}/absl-build"
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
|
|
3
oss-internship-2020/pffft/.gitignore
vendored
Normal file
3
oss-internship-2020/pffft/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
pffft_main
|
104
oss-internship-2020/pffft/CMakeLists.txt
Normal file
104
oss-internship-2020/pffft/CMakeLists.txt
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# Copyright 2020 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
project(pffft CXX C)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
|
add_library(pffft STATIC
|
||||||
|
master/pffft.c
|
||||||
|
master/pffft.h
|
||||||
|
master/fftpack.c
|
||||||
|
master/fftpack.h
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(pffft_main
|
||||||
|
master/test_pffft.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(pffft_main PRIVATE
|
||||||
|
pffft
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MATH_LIBS "")
|
||||||
|
include(CheckLibraryExists)
|
||||||
|
check_library_exists(m sin "" LIBM)
|
||||||
|
if(LIBM)
|
||||||
|
list(APPEND MATH_LIBS "m")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(pffft PUBLIC ${MATH_LIBS})
|
||||||
|
|
||||||
|
# Adding dependencies
|
||||||
|
set(SAPI_ROOT "../.." CACHE PATH "Path to the Sandboxed API source tree")
|
||||||
|
# Then configure:
|
||||||
|
# mkdir -p build && cd build
|
||||||
|
# cmake .. -G Ninja -DSAPI_ROOT=$HOME/sapi_root
|
||||||
|
|
||||||
|
set(SAPI_ENABLE_EXAMPLES OFF CACHE BOOL "")
|
||||||
|
set(SAPI_ENABLE_TESTS OFF CACHE BOOL "")
|
||||||
|
add_subdirectory("${SAPI_ROOT}"
|
||||||
|
"${CMAKE_BINARY_DIR}/sandboxed-api-build"
|
||||||
|
# Omit this to have the full Sandboxed API in IDE
|
||||||
|
EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_sapi_library(pffft_sapi
|
||||||
|
FUNCTIONS pffft_new_setup
|
||||||
|
pffft_destroy_setup
|
||||||
|
pffft_transform
|
||||||
|
pffft_transform_ordered
|
||||||
|
pffft_zreorder
|
||||||
|
pffft_zconvolve_accumulate
|
||||||
|
pffft_aligned_malloc
|
||||||
|
pffft_aligned_free
|
||||||
|
pffft_simd_size
|
||||||
|
cffti
|
||||||
|
cfftf
|
||||||
|
cfftb
|
||||||
|
rffti
|
||||||
|
rfftf
|
||||||
|
rfftb
|
||||||
|
cosqi
|
||||||
|
cosqf
|
||||||
|
cosqb
|
||||||
|
costi
|
||||||
|
cost
|
||||||
|
sinqi
|
||||||
|
sinqb
|
||||||
|
sinqf
|
||||||
|
sinti
|
||||||
|
sint
|
||||||
|
|
||||||
|
INPUTS master/pffft.h master/fftpack.h
|
||||||
|
LIBRARY pffft
|
||||||
|
LIBRARY_NAME Pffft
|
||||||
|
|
||||||
|
NAMESPACE ""
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(pffft_sapi INTERFACE
|
||||||
|
"${PROJECT_BINARY_DIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(pffft_sandboxed
|
||||||
|
main_pffft_sandboxed.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(pffft_sandboxed PRIVATE
|
||||||
|
pffft_sapi
|
||||||
|
sapi::sapi
|
||||||
|
)
|
87
oss-internship-2020/pffft/README.md
Normal file
87
oss-internship-2020/pffft/README.md
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# Sandboxing PFFFT library
|
||||||
|
|
||||||
|
Build System: CMake
|
||||||
|
OS: Linux
|
||||||
|
|
||||||
|
### Check out the PFFFT library & CMake set up
|
||||||
|
```
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
mkdir -p build && cd build
|
||||||
|
cmake .. -G Ninja -DPFFFT_ROOT_DIR=$PWD
|
||||||
|
ninjas
|
||||||
|
```
|
||||||
|
### For testing:
|
||||||
|
`cd build`, then `./pffft_sandboxed`
|
||||||
|
|
||||||
|
### For debug:
|
||||||
|
display custom info with
|
||||||
|
`./pffft_sandboxed --logtostderr`
|
||||||
|
|
||||||
|
## ***About the project***
|
||||||
|
*PFFFT library is concerned with 1D Fast-Fourier Transformations finding a
|
||||||
|
compromise between accuracy and speed. It deals with real and complex
|
||||||
|
vectors, both cases being illustrated in the testing part (`test_pffft.c`
|
||||||
|
for initially and original version, `main_pffft_sandboxed.cc` for our
|
||||||
|
currently implemented sandboxed version).
|
||||||
|
The original files can be found at: https://bitbucket.org/jpommier/pffft/src.*
|
||||||
|
|
||||||
|
*The purpose of sandboxing is to limit the permissions and capabilities of
|
||||||
|
library’s methods, in order to secure the usage of them.
|
||||||
|
After obtaining the sandbox, the functions will be called through an
|
||||||
|
Sandbox API (being called `api` in the current test) and so, the
|
||||||
|
operations, system calls or namspaces access may be controlled.
|
||||||
|
From both `pffft.h` and `fftpack.h` headers, useful methods are added to
|
||||||
|
sapi library builded with CMake. There is also a need to link math library
|
||||||
|
as the transformations made require mathematical operators.
|
||||||
|
Regarding the testing of the methods, one main is doing this job by
|
||||||
|
iterating through a set of values, that represents the accuracy of
|
||||||
|
transformations and print the speed for each value and type of
|
||||||
|
transformation. More specifically, the input length is the target for
|
||||||
|
accuracy (named as `n`) and it stands for the number of data points from
|
||||||
|
the series that calculate the result of transformation. It is also
|
||||||
|
important to mention that the `complex` variable stands for a boolean value
|
||||||
|
that tells the type of transformation (0 for REAL and 1 for COMPLEX) and
|
||||||
|
it is taken into account while testing.
|
||||||
|
In the end, the performance of PFFFT library it is outlined by the output.
|
||||||
|
There are two output formats available, from which you can choose through
|
||||||
|
`--output_format=` command-line flag.
|
||||||
|
Without using this type of argument when running, the output format is set
|
||||||
|
by default.*
|
||||||
|
|
||||||
|
#### CMake observations resume:
|
||||||
|
* linking pffft and fftpack (which contains necessary functions for pffft)
|
||||||
|
* set math library
|
||||||
|
|
||||||
|
#### Sandboxed main observations resume:
|
||||||
|
* containing two testing parts (fft / pffft benchmarks)
|
||||||
|
* showing the performance of the transformations implies
|
||||||
|
testing them through various FFT dimenstions.
|
||||||
|
Variable n, the input length, will take specific values
|
||||||
|
meaning the number of points to which it is set the calculus
|
||||||
|
(more details of mathematical purpose of n - https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm).
|
||||||
|
* output shows speed depending on the input length
|
||||||
|
* use `--output_format=0` or `--output_format=1` arguments to choose between output formats.
|
||||||
|
`0` is for a detailed output, while `1` is only displaying each transformation process speed.
|
||||||
|
|
||||||
|
### Bugs history
|
||||||
|
1. [Solved] pffft benchmark bug: "Sandbox not active"
|
||||||
|
|
||||||
|
n = 64, status OK, `pffft_transform` generates error
|
||||||
|
n > 64, status not OK
|
||||||
|
Problem on initialising `sapi::StatusOr<PFFFT_Setup *> s;` the memory that stays
|
||||||
|
for s is not the same with the address passed in `pffft_transform` function.
|
||||||
|
(`sapi::v::GenericPtr` - to be changed)
|
||||||
|
|
||||||
|
Temporary solution: change the generated files to accept
|
||||||
|
`uintptr_t` instead of `PFFFT_Setup`
|
||||||
|
|
||||||
|
Solution: using `sapi::v::RemotePtr` instead of `sapi::v::GenericPtr`
|
||||||
|
to access the memory of object `s`
|
||||||
|
|
||||||
|
2. [Unresolved] compiling bug: "No space left on device"
|
||||||
|
|
||||||
|
The building process creates some `embed` files that use lots of
|
||||||
|
memory, trying to write them on `/tmp`.
|
||||||
|
|
||||||
|
Temporary solution: clean /tmp directory by `sudo rm -rf /tmp/*`
|
207
oss-internship-2020/pffft/main_pffft_sandboxed.cc
Normal file
207
oss-internship-2020/pffft/main_pffft_sandboxed.cc
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
// Copyright 2020 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include "pffft_sapi.sapi.h" // NOLINT(build/include)
|
||||||
|
#include "sandboxed_api/util/flag.h"
|
||||||
|
#include "sandboxed_api/vars.h"
|
||||||
|
|
||||||
|
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all);
|
||||||
|
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all_and_log);
|
||||||
|
|
||||||
|
class PffftSapiSandbox : public PffftSandbox {
|
||||||
|
public:
|
||||||
|
std::unique_ptr<sandbox2::Policy> ModifyPolicy(sandbox2::PolicyBuilder*) {
|
||||||
|
return sandbox2::PolicyBuilder()
|
||||||
|
.AllowStaticStartup()
|
||||||
|
.AllowOpen()
|
||||||
|
.AllowRead()
|
||||||
|
.AllowWrite()
|
||||||
|
.AllowSystemMalloc()
|
||||||
|
.AllowExit()
|
||||||
|
.AllowSyscalls({
|
||||||
|
__NR_futex,
|
||||||
|
__NR_close,
|
||||||
|
__NR_getrusage,
|
||||||
|
})
|
||||||
|
.BuildOrDie();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// output_format flag determines whether the output shows information in detail
|
||||||
|
// or not. By default, the flag is set as 0, meaning an elaborate display
|
||||||
|
// (see ShowOutput method).
|
||||||
|
static bool ValidateFlag(const char* flagname, int32_t value) {
|
||||||
|
if (value >= 0 && value < 32768) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(ERROR) << "Invalid value for --" << flagname << ".";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_int32(output_format, 0, "Value to specific the output format.");
|
||||||
|
DEFINE_validator(output_format, &ValidateFlag);
|
||||||
|
|
||||||
|
double UclockSec() { return static_cast<double>(clock()) / CLOCKS_PER_SEC; }
|
||||||
|
|
||||||
|
void ShowOutput(const char* name, int n, int complex, float flops, float t0,
|
||||||
|
float t1, int max_iter) {
|
||||||
|
float mflops = flops / 1e6 / (t1 - t0 + 1e-16);
|
||||||
|
if (FLAGS_output_format) {
|
||||||
|
if (flops != -1) {
|
||||||
|
printf("|%9.0f ", mflops);
|
||||||
|
} else {
|
||||||
|
printf("| n/a ");
|
||||||
|
}
|
||||||
|
} else if (flops != -1) {
|
||||||
|
printf("n=%5d, %s %16s : %6.0f MFlops [t=%6.0f ns, %d runs]\n", n,
|
||||||
|
(complex ? "CPLX" : "REAL"), name, mflops,
|
||||||
|
(t1 - t0) / 2 / max_iter * 1e9, max_iter);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status PffftMain() {
|
||||||
|
LOG(INFO) << "Initializing sandbox...\n";
|
||||||
|
|
||||||
|
PffftSapiSandbox sandbox;
|
||||||
|
SAPI_RETURN_IF_ERROR(sandbox.Init());
|
||||||
|
|
||||||
|
PffftApi api(&sandbox);
|
||||||
|
|
||||||
|
// kTransformSizes is a vector keeping the values by which iterates n, its
|
||||||
|
// value representing the input length. More concrete, n is the number of data
|
||||||
|
// points the caclulus is up to (determinating its accuracy). To show the
|
||||||
|
// performance of Fast-Fourier Transformations the program is testing for
|
||||||
|
// various values of n.
|
||||||
|
constexpr int kTransformSizes[] = {
|
||||||
|
64, 96, 128, 160, 192, 256, 384, 5 * 96, 512, 5 * 128,
|
||||||
|
3 * 256, 800, 1024, 2048, 2400, 4096, 8192, 9 * 1024, 16384, 32768};
|
||||||
|
|
||||||
|
for (int complex : {0, 1}) {
|
||||||
|
for (int n : kTransformSizes) {
|
||||||
|
const int n_float = n * (complex ? 2 : 1);
|
||||||
|
int n_bytes = n_float * sizeof(float);
|
||||||
|
|
||||||
|
std::vector<float> work(2 * n_float + 15, 0.0);
|
||||||
|
sapi::v::Array<float> work_array(&work[0], work.size());
|
||||||
|
|
||||||
|
std::vector<float> x(n_bytes, 0.0);
|
||||||
|
sapi::v::Array<float> x_array(&x[0], x.size());
|
||||||
|
|
||||||
|
std::vector<float> y(n_bytes, 0.0);
|
||||||
|
sapi::v::Array<float> y_array(&y[0], y.size());
|
||||||
|
|
||||||
|
std::vector<float> z(n_bytes, 0.0);
|
||||||
|
sapi::v::Array<float> z_array(&z[0], z.size());
|
||||||
|
|
||||||
|
double t0;
|
||||||
|
double t1;
|
||||||
|
double flops;
|
||||||
|
|
||||||
|
int max_iter = 5120000 / n * 4;
|
||||||
|
|
||||||
|
for (int k = 0; k < n_float; ++k) {
|
||||||
|
x[k] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FFTPack benchmark
|
||||||
|
{
|
||||||
|
// SIMD_SZ == 4 (returning value of pffft_simd_size())
|
||||||
|
int simd_size_iter = max_iter / 4;
|
||||||
|
|
||||||
|
if (simd_size_iter == 0) simd_size_iter = 1;
|
||||||
|
if (complex) {
|
||||||
|
SAPI_RETURN_IF_ERROR(api.cffti(n, work_array.PtrBoth()))
|
||||||
|
} else {
|
||||||
|
SAPI_RETURN_IF_ERROR(api.rffti(n, work_array.PtrBoth()));
|
||||||
|
}
|
||||||
|
t0 = UclockSec();
|
||||||
|
|
||||||
|
for (int iter = 0; iter < simd_size_iter; ++iter) {
|
||||||
|
if (complex) {
|
||||||
|
SAPI_RETURN_IF_ERROR(
|
||||||
|
api.cfftf(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||||
|
SAPI_RETURN_IF_ERROR(
|
||||||
|
api.cfftb(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||||
|
} else {
|
||||||
|
SAPI_RETURN_IF_ERROR(
|
||||||
|
api.rfftf(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||||
|
SAPI_RETURN_IF_ERROR(
|
||||||
|
api.rfftb(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t1 = UclockSec();
|
||||||
|
|
||||||
|
flops = (simd_size_iter * 2) *
|
||||||
|
((complex ? 5 : 2.5) * static_cast<double>(n) *
|
||||||
|
log(static_cast<double>(n)) / M_LN2);
|
||||||
|
ShowOutput("FFTPack", n, complex, flops, t0, t1, simd_size_iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PFFFT benchmark
|
||||||
|
{
|
||||||
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
|
PFFFT_Setup * s,
|
||||||
|
api.pffft_new_setup(n, complex ? PFFFT_COMPLEX : PFFFT_REAL));
|
||||||
|
|
||||||
|
sapi::v::RemotePtr s_reg(s);
|
||||||
|
|
||||||
|
t0 = UclockSec();
|
||||||
|
for (int iter = 0; iter < max_iter; ++iter) {
|
||||||
|
SAPI_RETURN_IF_ERROR(
|
||||||
|
api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
|
||||||
|
y_array.PtrBoth(), PFFFT_FORWARD));
|
||||||
|
SAPI_RETURN_IF_ERROR(
|
||||||
|
api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
|
||||||
|
y_array.PtrBoth(), PFFFT_FORWARD));
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = UclockSec();
|
||||||
|
SAPI_RETURN_IF_ERROR(api.pffft_destroy_setup(&s_reg));
|
||||||
|
|
||||||
|
flops = (max_iter * 2) * ((complex ? 5 : 2.5) * static_cast<double>(n) *
|
||||||
|
log(static_cast<double>(n)) / M_LN2);
|
||||||
|
ShowOutput("PFFFT", n, complex, flops, t0, t1, max_iter);
|
||||||
|
|
||||||
|
LOG(INFO) << "n = " << n << " SUCCESSFULLY";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
// Initialize Google's logging library.
|
||||||
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
|
||||||
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
|
if (absl::Status status = PffftMain(); !status.ok()) {
|
||||||
|
LOG(ERROR) << "Initialization failed: " << status.ToString();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -147,10 +147,10 @@ cc_library(
|
||||||
":var_type",
|
":var_type",
|
||||||
"//sandboxed_api/sandbox2:comms",
|
"//sandboxed_api/sandbox2:comms",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
"@com_google_absl//absl/synchronization",
|
"@com_google_absl//absl/synchronization",
|
||||||
|
|
|
@ -43,6 +43,8 @@ add_library(sapi_embed_file STATIC
|
||||||
add_library(sapi::embed_file ALIAS sapi_embed_file)
|
add_library(sapi::embed_file ALIAS sapi_embed_file)
|
||||||
target_link_libraries(sapi_embed_file PRIVATE
|
target_link_libraries(sapi_embed_file PRIVATE
|
||||||
absl::flat_hash_map
|
absl::flat_hash_map
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::strings
|
absl::strings
|
||||||
absl::synchronization
|
absl::synchronization
|
||||||
glog::glog
|
glog::glog
|
||||||
|
@ -65,6 +67,8 @@ add_library(sapi::sapi ALIAS sapi_sapi)
|
||||||
target_link_libraries(sapi_sapi
|
target_link_libraries(sapi_sapi
|
||||||
PRIVATE absl::flat_hash_map
|
PRIVATE absl::flat_hash_map
|
||||||
absl::memory
|
absl::memory
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
absl::synchronization
|
absl::synchronization
|
||||||
|
@ -76,7 +80,6 @@ target_link_libraries(sapi_sapi
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
sapi::embed_file
|
sapi::embed_file
|
||||||
sapi::status
|
|
||||||
sapi::vars
|
sapi::vars
|
||||||
PUBLIC absl::core_headers
|
PUBLIC absl::core_headers
|
||||||
sandbox2::client
|
sandbox2::client
|
||||||
|
@ -137,6 +140,8 @@ add_library(sapi_vars STATIC
|
||||||
add_library(sapi::vars ALIAS sapi_vars)
|
add_library(sapi::vars ALIAS sapi_vars)
|
||||||
target_link_libraries(sapi_vars PRIVATE
|
target_link_libraries(sapi_vars PRIVATE
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
absl::synchronization
|
absl::synchronization
|
||||||
|
@ -147,7 +152,6 @@ target_link_libraries(sapi_vars PRIVATE
|
||||||
sapi::lenval_core
|
sapi::lenval_core
|
||||||
sapi::proto_arg_proto
|
sapi::proto_arg_proto
|
||||||
sapi::status
|
sapi::status
|
||||||
sapi::statusor
|
|
||||||
sapi::var_type
|
sapi::var_type
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -178,6 +182,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
)
|
)
|
||||||
target_link_libraries(sapi_test PRIVATE
|
target_link_libraries(sapi_test PRIVATE
|
||||||
absl::memory
|
absl::memory
|
||||||
|
absl::status
|
||||||
benchmark
|
benchmark
|
||||||
sapi::sapi
|
sapi::sapi
|
||||||
sapi::status
|
sapi::status
|
||||||
|
|
|
@ -34,9 +34,9 @@ def sapi_deps():
|
||||||
maybe(
|
maybe(
|
||||||
http_archive,
|
http_archive,
|
||||||
name = "com_google_absl",
|
name = "com_google_absl",
|
||||||
sha256 = "6668ada01192e2b95b42bb3668cfa5282c047de5176f5e567028e12f8bfb8aef", # 2020-04-28
|
sha256 = "8061df0ebbd3f599bcd3f5e57fb8003564d50a9b6a81a7f968fb0196b952365d", # 2020-09-02
|
||||||
strip_prefix = "abseil-cpp-6e18c7115df9b7ca0987cc346b1b1d4b3cc829b3",
|
strip_prefix = "abseil-cpp-0e9921b75a0fdd639a504ec8443fc1fe801becd7",
|
||||||
urls = ["https://github.com/abseil/abseil-cpp/archive/6e18c7115df9b7ca0987cc346b1b1d4b3cc829b3.zip"],
|
urls = ["https://github.com/abseil/abseil-cpp/archive/0e9921b75a0fdd639a504ec8443fc1fe801becd7.zip"],
|
||||||
)
|
)
|
||||||
maybe(
|
maybe(
|
||||||
http_archive,
|
http_archive,
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
|
|
||||||
# Description: Sandboxed API reimplementation of zlib's zpipe.c example.
|
# Description: Sandboxed API reimplementation of zlib's zpipe.c example.
|
||||||
|
|
||||||
licenses(["notice"])
|
|
||||||
|
|
||||||
load("//sandboxed_api/bazel:build_defs.bzl", "sapi_platform_copts")
|
load("//sandboxed_api/bazel:build_defs.bzl", "sapi_platform_copts")
|
||||||
load("//sandboxed_api/bazel:sapi.bzl", "sapi_library")
|
load("//sandboxed_api/bazel:sapi.bzl", "sapi_library")
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
sapi_library(
|
sapi_library(
|
||||||
name = "zlib-sapi",
|
name = "zlib-sapi",
|
||||||
srcs = [],
|
srcs = [],
|
||||||
|
@ -43,5 +43,6 @@ cc_binary(
|
||||||
"//sandboxed_api:vars",
|
"//sandboxed_api:vars",
|
||||||
"//sandboxed_api/util:flags",
|
"//sandboxed_api/util:flags",
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,11 +32,11 @@ add_executable(main_zlib
|
||||||
main_zlib.cc
|
main_zlib.cc
|
||||||
)
|
)
|
||||||
target_link_libraries(main_zlib PRIVATE
|
target_link_libraries(main_zlib PRIVATE
|
||||||
|
absl::status
|
||||||
sapi::base
|
sapi::base
|
||||||
glog::glog
|
glog::glog
|
||||||
sapi::flags
|
sapi::flags
|
||||||
sapi::sapi
|
sapi::sapi
|
||||||
sapi::status
|
sapi::status
|
||||||
sapi::statusor
|
|
||||||
sapi::zlib_sapi
|
sapi::zlib_sapi
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "absl/base/macros.h"
|
#include "absl/base/macros.h"
|
||||||
#include "sandboxed_api/util/flag.h"
|
#include "sandboxed_api/util/flag.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "sandboxed_api/examples/zlib/zlib-sapi.sapi.h"
|
#include "sandboxed_api/examples/zlib/zlib-sapi.sapi.h"
|
||||||
#include "sandboxed_api/examples/zlib/zlib-sapi_embed.h"
|
#include "sandboxed_api/examples/zlib/zlib-sapi_embed.h"
|
||||||
#include "sandboxed_api/vars.h"
|
#include "sandboxed_api/vars.h"
|
||||||
|
@ -47,7 +48,7 @@ int main(int argc, char** argv) {
|
||||||
<< status.message();
|
<< status.message();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<int> ret;
|
absl::StatusOr<int> ret;
|
||||||
int flush;
|
int flush;
|
||||||
unsigned have;
|
unsigned have;
|
||||||
sapi::v::Struct<sapi::zlib::z_stream> strm;
|
sapi::v::Struct<sapi::zlib::z_stream> strm;
|
||||||
|
|
|
@ -22,13 +22,13 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "sandboxed_api/proto_arg.pb.h"
|
#include "sandboxed_api/proto_arg.pb.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
sapi::StatusOr<std::vector<uint8_t>> SerializeProto(const T& proto) {
|
absl::StatusOr<std::vector<uint8_t>> SerializeProto(const T& proto) {
|
||||||
static_assert(std::is_base_of<google::protobuf::Message, T>::value,
|
static_assert(std::is_base_of<google::protobuf::Message, T>::value,
|
||||||
"Template argument must be a proto message");
|
"Template argument must be a proto message");
|
||||||
// Wrap protobuf in a envelope so that we know the name of the protobuf
|
// Wrap protobuf in a envelope so that we know the name of the protobuf
|
||||||
|
@ -46,7 +46,7 @@ sapi::StatusOr<std::vector<uint8_t>> SerializeProto(const T& proto) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
sapi::StatusOr<T> DeserializeProto(const char* data, size_t len) {
|
absl::StatusOr<T> DeserializeProto(const char* data, size_t len) {
|
||||||
static_assert(std::is_base_of<google::protobuf::Message, T>::value,
|
static_assert(std::is_base_of<google::protobuf::Message, T>::value,
|
||||||
"Template argument must be a proto message");
|
"Template argument must be a proto message");
|
||||||
ProtoArg envelope;
|
ProtoArg envelope;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "sandboxed_api/rpcchannel.h"
|
#include "sandboxed_api/rpcchannel.h"
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/synchronization/mutex.h"
|
#include "absl/synchronization/mutex.h"
|
||||||
#include "sandboxed_api/call.h"
|
#include "sandboxed_api/call.h"
|
||||||
|
@ -35,7 +36,7 @@ absl::Status RPCChannel::Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<FuncRet> RPCChannel::Return(v::Type exp_type) {
|
absl::StatusOr<FuncRet> RPCChannel::Return(v::Type exp_type) {
|
||||||
uint32_t tag;
|
uint32_t tag;
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
FuncRet ret;
|
FuncRet ret;
|
||||||
|
@ -202,7 +203,7 @@ absl::Status RPCChannel::Close(int remote_fd) {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<uint64_t> RPCChannel::Strlen(void* str) {
|
absl::StatusOr<uint64_t> RPCChannel::Strlen(void* str) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
if (!comms_->SendTLV(comms::kMsgStrlen, sizeof(str),
|
if (!comms_->SendTLV(comms::kMsgStrlen, sizeof(str),
|
||||||
reinterpret_cast<uint8_t*>(&str))) {
|
reinterpret_cast<uint8_t*>(&str))) {
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/synchronization/mutex.h"
|
#include "absl/synchronization/mutex.h"
|
||||||
#include "sandboxed_api/call.h"
|
#include "sandboxed_api/call.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
#include "sandboxed_api/var_type.h"
|
#include "sandboxed_api/var_type.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
|
|
||||||
|
@ -61,13 +61,13 @@ class RPCChannel {
|
||||||
absl::Status Close(int remote_fd);
|
absl::Status Close(int remote_fd);
|
||||||
|
|
||||||
// Returns length of a null-terminated c-style string (invokes strlen).
|
// Returns length of a null-terminated c-style string (invokes strlen).
|
||||||
sapi::StatusOr<uint64_t> Strlen(void* str);
|
absl::StatusOr<uint64_t> Strlen(void* str);
|
||||||
|
|
||||||
sandbox2::Comms* comms() const { return comms_; }
|
sandbox2::Comms* comms() const { return comms_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Receives the result after a call.
|
// Receives the result after a call.
|
||||||
sapi::StatusOr<FuncRet> Return(v::Type exp_type);
|
absl::StatusOr<FuncRet> Return(v::Type exp_type);
|
||||||
|
|
||||||
sandbox2::Comms* comms_; // Owned by sandbox2;
|
sandbox2::Comms* comms_; // Owned by sandbox2;
|
||||||
absl::Mutex mutex_;
|
absl::Mutex mutex_;
|
||||||
|
|
|
@ -84,7 +84,9 @@ void InitDefaultPolicyBuilder(sandbox2::PolicyBuilder* builder) {
|
||||||
__NR_kill,
|
__NR_kill,
|
||||||
__NR_tgkill,
|
__NR_tgkill,
|
||||||
__NR_tkill,
|
__NR_tkill,
|
||||||
|
#ifdef __NR_readlink
|
||||||
__NR_readlink,
|
__NR_readlink,
|
||||||
|
#endif
|
||||||
#ifdef __NR_arch_prctl // x86-64 only
|
#ifdef __NR_arch_prctl // x86-64 only
|
||||||
__NR_arch_prctl,
|
__NR_arch_prctl,
|
||||||
#endif
|
#endif
|
||||||
|
@ -391,8 +393,8 @@ absl::Status Sandbox::TransferFromSandboxee(v::Var* var) {
|
||||||
return var->TransferFromSandboxee(GetRpcChannel(), pid());
|
return var->TransferFromSandboxee(GetRpcChannel(), pid());
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> Sandbox::GetCString(const v::RemotePtr& str,
|
absl::StatusOr<std::string> Sandbox::GetCString(const v::RemotePtr& str,
|
||||||
uint64_t max_length) {
|
uint64_t max_length) {
|
||||||
if (!is_active()) {
|
if (!is_active()) {
|
||||||
return absl::UnavailableError("Sandbox not active");
|
return absl::UnavailableError("Sandbox not active");
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,9 @@ class Sandbox {
|
||||||
absl::Status TransferToSandboxee(v::Var* var);
|
absl::Status TransferToSandboxee(v::Var* var);
|
||||||
absl::Status TransferFromSandboxee(v::Var* var);
|
absl::Status TransferFromSandboxee(v::Var* var);
|
||||||
|
|
||||||
sapi::StatusOr<std::string> GetCString(
|
absl::StatusOr<std::string> GetCString(const v::RemotePtr& str,
|
||||||
const v::RemotePtr& str, uint64_t max_length = 10ULL << 20 /* 10 MiB*/
|
uint64_t max_length = 10ULL
|
||||||
|
<< 20 /* 10 MiB*/
|
||||||
);
|
);
|
||||||
|
|
||||||
// Waits until the sandbox terminated and returns the result.
|
// Waits until the sandbox terminated and returns the result.
|
||||||
|
|
|
@ -26,6 +26,13 @@ licenses(["notice"]) # Apache 2.0
|
||||||
|
|
||||||
exports_files(["testdata/hostname"])
|
exports_files(["testdata/hostname"])
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "config",
|
||||||
|
hdrs = ["config.h"],
|
||||||
|
copts = sapi_platform_copts(),
|
||||||
|
deps = ["@com_google_absl//absl/base:config"],
|
||||||
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "bpfdisassembler",
|
name = "bpfdisassembler",
|
||||||
srcs = ["bpfdisassembler.cc"],
|
srcs = ["bpfdisassembler.cc"],
|
||||||
|
@ -40,6 +47,7 @@ cc_library(
|
||||||
hdrs = ["regs.h"],
|
hdrs = ["regs.h"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":syscall",
|
":syscall",
|
||||||
":violation_cc_proto",
|
":violation_cc_proto",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
|
@ -60,6 +68,7 @@ cc_library(
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":util",
|
":util",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
|
@ -73,6 +82,7 @@ cc_test(
|
||||||
srcs = ["syscall_test.cc"],
|
srcs = ["syscall_test.cc"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":syscall",
|
":syscall",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_googletest//:gtest_main",
|
"@com_google_googletest//:gtest_main",
|
||||||
|
@ -85,12 +95,13 @@ cc_library(
|
||||||
hdrs = ["result.h"],
|
hdrs = ["result.h"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":regs",
|
":regs",
|
||||||
":syscall",
|
":syscall",
|
||||||
":util",
|
":util",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -272,6 +283,7 @@ cc_library(
|
||||||
deps = [
|
deps = [
|
||||||
":client",
|
":client",
|
||||||
":comms",
|
":comms",
|
||||||
|
":config",
|
||||||
":executor",
|
":executor",
|
||||||
":fork_client",
|
":fork_client",
|
||||||
":forkserver_cc_proto",
|
":forkserver_cc_proto",
|
||||||
|
@ -300,12 +312,12 @@ cc_library(
|
||||||
"//sandboxed_api/util:flags",
|
"//sandboxed_api/util:flags",
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/container:flat_hash_map",
|
"@com_google_absl//absl/container:flat_hash_map",
|
||||||
"@com_google_absl//absl/container:flat_hash_set",
|
"@com_google_absl//absl/container:flat_hash_set",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
"@com_google_absl//absl/synchronization",
|
"@com_google_absl//absl/synchronization",
|
||||||
|
@ -374,9 +386,9 @@ cc_library(
|
||||||
"//sandboxed_api/sandbox2/util:fileops",
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
"@org_kernel_libcap//:libcap",
|
"@org_kernel_libcap//:libcap",
|
||||||
|
@ -404,6 +416,7 @@ cc_library(
|
||||||
hdrs = ["mounts.h"],
|
hdrs = ["mounts.h"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":mounttree_cc_proto",
|
":mounttree_cc_proto",
|
||||||
"//sandboxed_api/sandbox2/util:file_base",
|
"//sandboxed_api/sandbox2/util:file_base",
|
||||||
"//sandboxed_api/sandbox2/util:fileops",
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
|
@ -411,10 +424,10 @@ cc_library(
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/container:flat_hash_set",
|
"@com_google_absl//absl/container:flat_hash_set",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_protobuf//:protobuf",
|
"@com_google_protobuf//:protobuf",
|
||||||
],
|
],
|
||||||
|
@ -468,6 +481,7 @@ cc_test(
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
":comms",
|
":comms",
|
||||||
|
":config",
|
||||||
":namespace",
|
":namespace",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
|
@ -505,12 +519,13 @@ cc_library(
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
"//sandboxed_api/sandbox2/util:file_base",
|
"//sandboxed_api/sandbox2/util:file_base",
|
||||||
"//sandboxed_api/sandbox2/util:fileops",
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
],
|
],
|
||||||
|
@ -526,9 +541,9 @@ cc_library(
|
||||||
":util",
|
":util",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -541,6 +556,7 @@ cc_test(
|
||||||
deps = [
|
deps = [
|
||||||
":buffer",
|
":buffer",
|
||||||
":comms",
|
":comms",
|
||||||
|
":config",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
"//sandboxed_api/util:status_matchers",
|
"//sandboxed_api/util:status_matchers",
|
||||||
|
@ -573,10 +589,10 @@ cc_library(
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:status_proto",
|
"//sandboxed_api/util:status_proto",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
"@com_google_absl//absl/synchronization",
|
"@com_google_absl//absl/synchronization",
|
||||||
|
@ -629,6 +645,7 @@ cc_test(
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
data = ["//sandboxed_api/sandbox2/testcases:limits"],
|
data = ["//sandboxed_api/sandbox2/testcases:limits"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":limits",
|
":limits",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
|
@ -671,6 +688,7 @@ cc_test(
|
||||||
"//sandboxed_api/sandbox2/testcases:policy",
|
"//sandboxed_api/sandbox2/testcases:policy",
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":limits",
|
":limits",
|
||||||
":regs",
|
":regs",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
|
@ -695,6 +713,7 @@ cc_test(
|
||||||
],
|
],
|
||||||
tags = ["local"],
|
tags = ["local"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":sandbox2",
|
":sandbox2",
|
||||||
":testing",
|
":testing",
|
||||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||||
|
@ -805,6 +824,7 @@ cc_test(
|
||||||
"//sandboxed_api/util:status_matchers",
|
"//sandboxed_api/util:status_matchers",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_glog//:glog",
|
"@com_google_glog//:glog",
|
||||||
"@com_google_googletest//:gtest_main",
|
"@com_google_googletest//:gtest_main",
|
||||||
|
|
|
@ -17,6 +17,16 @@ add_subdirectory(unwind)
|
||||||
add_subdirectory(util)
|
add_subdirectory(util)
|
||||||
add_subdirectory(network_proxy)
|
add_subdirectory(network_proxy)
|
||||||
|
|
||||||
|
# sandboxed_api/sandbox2:config
|
||||||
|
add_library(sandbox2_config STATIC
|
||||||
|
config.h
|
||||||
|
)
|
||||||
|
add_library(sandbox2::config ALIAS sandbox2_config)
|
||||||
|
target_link_libraries(sandbox2_config PRIVATE
|
||||||
|
absl::config
|
||||||
|
sapi::base
|
||||||
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2:bpfdisassembler
|
# sandboxed_api/sandbox2:bpfdisassembler
|
||||||
add_library(sandbox2_bpfdisassembler STATIC
|
add_library(sandbox2_bpfdisassembler STATIC
|
||||||
bpfdisassembler.cc
|
bpfdisassembler.cc
|
||||||
|
@ -37,6 +47,7 @@ add_library(sandbox2::regs ALIAS sandbox2_regs)
|
||||||
target_link_libraries(sandbox2_regs PRIVATE
|
target_link_libraries(sandbox2_regs PRIVATE
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sandbox2::syscall
|
sandbox2::syscall
|
||||||
sandbox2::violation_proto
|
sandbox2::violation_proto
|
||||||
|
@ -72,6 +83,7 @@ target_link_libraries(sandbox2_result PRIVATE
|
||||||
absl::base
|
absl::base
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::regs
|
sandbox2::regs
|
||||||
sandbox2::syscall
|
sandbox2::syscall
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
|
@ -271,6 +283,8 @@ target_link_libraries(sandbox2_sandbox2
|
||||||
absl::flat_hash_set
|
absl::flat_hash_set
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::optional
|
absl::optional
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
absl::synchronization
|
absl::synchronization
|
||||||
|
@ -278,6 +292,7 @@ target_link_libraries(sandbox2_sandbox2
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
sandbox2::client
|
sandbox2::client
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::executor
|
sandbox2::executor
|
||||||
sandbox2::file_base
|
sandbox2::file_base
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
|
@ -300,7 +315,6 @@ target_link_libraries(sandbox2_sandbox2
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
sandbox2::violation_proto
|
sandbox2::violation_proto
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::statusor
|
|
||||||
PUBLIC sapi::flags
|
PUBLIC sapi::flags
|
||||||
sapi::status
|
sapi::status
|
||||||
sandbox2::logsink
|
sandbox2::logsink
|
||||||
|
@ -351,6 +365,8 @@ add_library(sandbox2_forkserver STATIC
|
||||||
add_library(sandbox2::forkserver ALIAS sandbox2_forkserver)
|
add_library(sandbox2::forkserver ALIAS sandbox2_forkserver)
|
||||||
target_link_libraries(sandbox2_forkserver PRIVATE
|
target_link_libraries(sandbox2_forkserver PRIVATE
|
||||||
absl::memory
|
absl::memory
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
libcap::libcap
|
libcap::libcap
|
||||||
|
@ -369,7 +385,6 @@ target_link_libraries(sandbox2_forkserver PRIVATE
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::raw_logging
|
sapi::raw_logging
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2:fork_client
|
# sandboxed_api/sandbox2:fork_client
|
||||||
|
@ -397,9 +412,11 @@ target_link_libraries(sandbox2_mounts PRIVATE
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::flat_hash_set
|
absl::flat_hash_set
|
||||||
absl::status
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
protobuf::libprotobuf
|
protobuf::libprotobuf
|
||||||
|
sandbox2::config
|
||||||
sandbox2::file_base
|
sandbox2::file_base
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
sandbox2::minielf
|
sandbox2::minielf
|
||||||
|
@ -408,7 +425,6 @@ target_link_libraries(sandbox2_mounts PRIVATE
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::raw_logging
|
sapi::raw_logging
|
||||||
sapi::status
|
sapi::status
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2:namespace
|
# sandboxed_api/sandbox2:namespace
|
||||||
|
@ -458,13 +474,14 @@ target_link_libraries(sandbox2_util
|
||||||
PRIVATE absl::core_headers
|
PRIVATE absl::core_headers
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::file_base
|
sandbox2::file_base
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::raw_logging
|
sapi::raw_logging
|
||||||
sapi::statusor
|
|
||||||
PUBLIC absl::status
|
PUBLIC absl::status
|
||||||
|
absl::statusor
|
||||||
)
|
)
|
||||||
target_compile_options(sandbox2_util PRIVATE
|
target_compile_options(sandbox2_util PRIVATE
|
||||||
# The default is 16384, however we need to do a clone with a
|
# The default is 16384, however we need to do a clone with a
|
||||||
|
@ -482,12 +499,13 @@ add_library(sandbox2::buffer ALIAS sandbox2_buffer)
|
||||||
target_link_libraries(sandbox2_buffer PRIVATE
|
target_link_libraries(sandbox2_buffer PRIVATE
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::memory
|
absl::memory
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::status
|
sapi::status
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2:forkserver_proto
|
# sandboxed_api/sandbox2:forkserver_proto
|
||||||
|
@ -527,6 +545,8 @@ add_library(sandbox2_comms STATIC
|
||||||
add_library(sandbox2::comms ALIAS sandbox2_comms)
|
add_library(sandbox2::comms ALIAS sandbox2_comms)
|
||||||
target_link_libraries(sandbox2_comms
|
target_link_libraries(sandbox2_comms
|
||||||
PRIVATE absl::memory
|
PRIVATE absl::memory
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::str_format
|
absl::str_format
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
|
@ -534,7 +554,6 @@ target_link_libraries(sandbox2_comms
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::raw_logging
|
sapi::raw_logging
|
||||||
sapi::status_proto
|
sapi::status_proto
|
||||||
sapi::statusor
|
|
||||||
PUBLIC absl::core_headers
|
PUBLIC absl::core_headers
|
||||||
absl::status
|
absl::status
|
||||||
absl::synchronization
|
absl::synchronization
|
||||||
|
@ -566,6 +585,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
)
|
)
|
||||||
target_link_libraries(syscall_test PRIVATE
|
target_link_libraries(syscall_test PRIVATE
|
||||||
absl::strings
|
absl::strings
|
||||||
|
sandbox2::config
|
||||||
sandbox2::syscall
|
sandbox2::syscall
|
||||||
sapi::test_main
|
sapi::test_main
|
||||||
)
|
)
|
||||||
|
@ -604,6 +624,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
sandbox2::namespace
|
sandbox2::namespace
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
|
@ -628,6 +649,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
sandbox2::buffer
|
sandbox2::buffer
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
sandbox2::testing
|
sandbox2::testing
|
||||||
sapi::status_matchers
|
sapi::status_matchers
|
||||||
|
@ -702,6 +724,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
target_link_libraries(limits_test PRIVATE
|
target_link_libraries(limits_test PRIVATE
|
||||||
absl::memory
|
absl::memory
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
|
sandbox2::config
|
||||||
sandbox2::limits
|
sandbox2::limits
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
sandbox2::testing
|
sandbox2::testing
|
||||||
|
@ -751,6 +774,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
|
sandbox2::config
|
||||||
sandbox2::limits
|
sandbox2::limits
|
||||||
sandbox2::regs
|
sandbox2::regs
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
|
@ -776,6 +800,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
absl::memory
|
absl::memory
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
|
sandbox2::config
|
||||||
sandbox2::sandbox2
|
sandbox2::sandbox2
|
||||||
sandbox2::testing
|
sandbox2::testing
|
||||||
sapi::status_matchers
|
sapi::status_matchers
|
||||||
|
@ -832,6 +857,7 @@ if(SAPI_ENABLE_TESTS)
|
||||||
)
|
)
|
||||||
target_link_libraries(stack_trace_test PRIVATE
|
target_link_libraries(stack_trace_test PRIVATE
|
||||||
absl::memory
|
absl::memory
|
||||||
|
absl::status
|
||||||
absl::strings
|
absl::strings
|
||||||
sandbox2::bpf_helper
|
sandbox2::bpf_helper
|
||||||
sandbox2::fileops
|
sandbox2::fileops
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "sandboxed_api/sandbox2/util.h"
|
#include "sandboxed_api/sandbox2/util.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
|
@ -28,7 +29,7 @@
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
// Creates a new Buffer that is backed by the specified file descriptor.
|
// Creates a new Buffer that is backed by the specified file descriptor.
|
||||||
sapi::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateFromFd(int fd) {
|
absl::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateFromFd(int fd) {
|
||||||
auto buffer = absl::WrapUnique(new Buffer{});
|
auto buffer = absl::WrapUnique(new Buffer{});
|
||||||
|
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
|
@ -53,7 +54,7 @@ sapi::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateFromFd(int fd) {
|
||||||
|
|
||||||
// Creates a new Buffer of the specified size, backed by a temporary file that
|
// Creates a new Buffer of the specified size, backed by a temporary file that
|
||||||
// will be immediately deleted.
|
// will be immediately deleted.
|
||||||
sapi::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateWithSize(int64_t size) {
|
absl::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateWithSize(int64_t size) {
|
||||||
int fd;
|
int fd;
|
||||||
if (!util::CreateMemFd(&fd)) {
|
if (!util::CreateMemFd(&fd)) {
|
||||||
return absl::InternalError("Could not create buffer temp file");
|
return absl::InternalError("Could not create buffer temp file");
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "sandboxed_api/util/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
@ -37,11 +37,11 @@ class Buffer final {
|
||||||
// Creates a new Buffer that is backed by the specified file descriptor.
|
// Creates a new Buffer that is backed by the specified file descriptor.
|
||||||
// The Buffer takes ownership of the descriptor and will close it when
|
// The Buffer takes ownership of the descriptor and will close it when
|
||||||
// destroyed.
|
// destroyed.
|
||||||
static sapi::StatusOr<std::unique_ptr<Buffer>> CreateFromFd(int fd);
|
static absl::StatusOr<std::unique_ptr<Buffer>> CreateFromFd(int fd);
|
||||||
|
|
||||||
// Creates a new Buffer of the specified size, backed by a temporary file that
|
// Creates a new Buffer of the specified size, backed by a temporary file that
|
||||||
// will be immediately deleted.
|
// will be immediately deleted.
|
||||||
static sapi::StatusOr<std::unique_ptr<Buffer>> CreateWithSize(int64_t size);
|
static absl::StatusOr<std::unique_ptr<Buffer>> CreateWithSize(int64_t size);
|
||||||
|
|
||||||
// Returns a pointer to the buffer, which is read/write.
|
// Returns a pointer to the buffer, which is read/write.
|
||||||
uint8_t* data() const { return buf_; }
|
uint8_t* data() const { return buf_; }
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/ipc.h"
|
#include "sandboxed_api/sandbox2/ipc.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
|
@ -83,19 +84,20 @@ std::unique_ptr<Policy> BufferTestcasePolicy() {
|
||||||
.AllowSyscall(__NR_lseek)
|
.AllowSyscall(__NR_lseek)
|
||||||
.AllowSyscall(__NR_close)
|
.AllowSyscall(__NR_close)
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
|
#ifdef __NR_access
|
||||||
// On Debian, even static binaries check existence of
|
// On Debian, even static binaries check existence of
|
||||||
// /etc/ld.so.nohwcap.
|
// /etc/ld.so.nohwcap.
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef __NR_faccessat
|
||||||
|
.BlockSyscallWithErrno(__NR_faccessat, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
||||||
#if defined(__powerpc64__)
|
|
||||||
|
|
||||||
s2p->AllowUnsafeMmapFiles();
|
|
||||||
s2p->AllowUnsafeMmapShared();
|
|
||||||
#endif /* defined(__powerpc64__) */
|
|
||||||
|
|
||||||
return s2p;
|
return s2p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "google/protobuf/message.h"
|
#include "google/protobuf/message.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/synchronization/mutex.h"
|
#include "absl/synchronization/mutex.h"
|
||||||
|
@ -44,7 +45,6 @@
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
#include "sandboxed_api/util/raw_logging.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
#include "sandboxed_api/util/status.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
#ifdef MEMORY_SANITIZER
|
#ifdef MEMORY_SANITIZER
|
||||||
#include "base/dynamic_annotations.h"
|
#include "base/dynamic_annotations.h"
|
||||||
|
@ -347,7 +347,7 @@ bool Comms::RecvFD(int* fd) {
|
||||||
|
|
||||||
const auto op = [&msg](int fd) -> ssize_t {
|
const auto op = [&msg](int fd) -> ssize_t {
|
||||||
PotentiallyBlockingRegion region;
|
PotentiallyBlockingRegion region;
|
||||||
// Use syscall, otherwise we would need to whitelist socketcall() on PPC.
|
// Use syscall, otherwise we would need to allow socketcall() on PPC.
|
||||||
return TEMP_FAILURE_RETRY(
|
return TEMP_FAILURE_RETRY(
|
||||||
util::Syscall(__NR_recvmsg, fd, reinterpret_cast<uintptr_t>(&msg), 0));
|
util::Syscall(__NR_recvmsg, fd, reinterpret_cast<uintptr_t>(&msg), 0));
|
||||||
};
|
};
|
||||||
|
|
85
sandboxed_api/sandbox2/config.h
Normal file
85
sandboxed_api/sandbox2/config.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright 2020 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef SANDBOXED_API_SANDBOX2_CONFIG_H_
|
||||||
|
#define SANDBOXED_API_SANDBOX2_CONFIG_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "absl/base/config.h"
|
||||||
|
|
||||||
|
// GCC/Clang define __x86_64__, Visual Studio uses _M_X64
|
||||||
|
#if defined(__x86_64__) || defined(_M_X64)
|
||||||
|
#define SAPI_X86_64 1
|
||||||
|
|
||||||
|
// Check various spellings for 64-bit POWER. Not checking for Visual Studio, as
|
||||||
|
// it does not support 64-bit POWER.
|
||||||
|
#elif (defined(__PPC64__) || defined(__powerpc64__) || defined(__ppc64__)) && \
|
||||||
|
defined(ABSL_IS_LITTLE_ENDIAN)
|
||||||
|
#define SAPI_PPC64_LE 1
|
||||||
|
|
||||||
|
// Spellings for AArch64
|
||||||
|
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||||
|
#define SAPI_ARM64 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
namespace cpu {
|
||||||
|
|
||||||
|
// CPU architectures known to Sandbox2
|
||||||
|
enum Architecture : uint16_t {
|
||||||
|
// Linux: Use a magic value, so it can be easily spotted in the seccomp-bpf
|
||||||
|
// bytecode decompilation stream. Must be < (1<<15), as/ that's the size of
|
||||||
|
// data which can be returned by BPF.
|
||||||
|
kUnknown = 0xCAF0,
|
||||||
|
kX8664,
|
||||||
|
kX86,
|
||||||
|
kPPC64LE,
|
||||||
|
kArm64,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cpu
|
||||||
|
|
||||||
|
namespace host_cpu {
|
||||||
|
|
||||||
|
// Returns the current host CPU architecture if supported. If not supported,
|
||||||
|
// returns cpu::kUnknown.
|
||||||
|
constexpr cpu::Architecture Architecture() {
|
||||||
|
#if defined(SAPI_X86_64)
|
||||||
|
return cpu::kX8664;
|
||||||
|
#elif defined(SAPI_PPC64_LE)
|
||||||
|
return cpu::kPPC64LE;
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
return cpu::kArm64;
|
||||||
|
#else
|
||||||
|
return cpu::kUnknown;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsX8664() { return Architecture() == cpu::kX8664; }
|
||||||
|
|
||||||
|
constexpr bool IsPPC64LE() { return Architecture() == cpu::kPPC64LE; }
|
||||||
|
|
||||||
|
constexpr bool IsArm64() { return Architecture() == cpu::kArm64; }
|
||||||
|
|
||||||
|
} // namespace host_cpu
|
||||||
|
|
||||||
|
static_assert(host_cpu::Architecture() != cpu::kUnknown,
|
||||||
|
"Host CPU architecture is not supported: One of x86-64, POWER64 "
|
||||||
|
"(little endian) or AArch64 is required.");
|
||||||
|
|
||||||
|
} // namespace sandbox2
|
||||||
|
|
||||||
|
#endif // SANDBOXED_API_SANDBOX2_CONFIG_H_
|
|
@ -27,7 +27,6 @@ cc_binary(
|
||||||
deps = [
|
deps = [
|
||||||
"//sandboxed_api/sandbox2",
|
"//sandboxed_api/sandbox2",
|
||||||
"//sandboxed_api/sandbox2:comms",
|
"//sandboxed_api/sandbox2:comms",
|
||||||
"//sandboxed_api/sandbox2/network_proxy:filtering",
|
|
||||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||||
"//sandboxed_api/sandbox2/util:fileops",
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
"//sandboxed_api/sandbox2/util:runfiles",
|
"//sandboxed_api/sandbox2/util:runfiles",
|
||||||
|
@ -48,7 +47,9 @@ cc_binary(
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:flags",
|
"//sandboxed_api/util:flags",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:statusor",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -31,13 +31,14 @@ target_link_libraries(sandbox2_networkproxy_sandbox PRIVATE
|
||||||
sapi::flags
|
sapi::flags
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# sandboxed_api/sandbox2/examples/networkproxy:networkproxy_bin
|
# sandboxed_api/sandbox2/examples/networkproxy:networkproxy_bin
|
||||||
add_executable(sandbox2_networkproxy_bin
|
add_executable(sandbox2_networkproxy_bin
|
||||||
networkproxy_bin.cc
|
networkproxy_bin.cc
|
||||||
)
|
)
|
||||||
add_executable(sandbox2::networkproxy_bin ALIAS sandbox2_networkproxy_bin)
|
add_executable(sandbox2::networkproxy_bin ALIAS sandbox2_networkproxy_bin)
|
||||||
target_link_libraries(sandbox2_networkproxy_bin PRIVATE
|
target_link_libraries(sandbox2_networkproxy_bin PRIVATE
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::str_format
|
absl::str_format
|
||||||
glog::glog
|
glog::glog
|
||||||
gflags::gflags
|
gflags::gflags
|
||||||
|
@ -48,6 +49,4 @@ target_link_libraries(sandbox2_networkproxy_bin PRIVATE
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::flags
|
sapi::flags
|
||||||
sapi::status
|
sapi::status
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,16 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "sandboxed_api/util/flag.h"
|
#include "sandboxed_api/util/flag.h"
|
||||||
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "sandboxed_api/sandbox2/client.h"
|
#include "sandboxed_api/sandbox2/client.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
#include "sandboxed_api/sandbox2/network_proxy/client.h"
|
#include "sandboxed_api/sandbox2/network_proxy/client.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
ABSL_FLAG(bool, connect_with_handler, true, "Connect using automatic mode.");
|
ABSL_FLAG(bool, connect_with_handler, true, "Connect using automatic mode.");
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ absl::Status CommunicationTest(int sock) {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<struct sockaddr_in6> CreateAddres(int port) {
|
absl::StatusOr<struct sockaddr_in6> CreateAddres(int port) {
|
||||||
static struct sockaddr_in6 saddr {};
|
static struct sockaddr_in6 saddr {};
|
||||||
saddr.sin6_family = AF_INET6;
|
saddr.sin6_family = AF_INET6;
|
||||||
saddr.sin6_port = htons(port);
|
saddr.sin6_port = htons(port);
|
||||||
|
@ -86,7 +87,7 @@ absl::Status ConnectWithHandler(int s, const struct sockaddr_in6& saddr) {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<int> ConnectToServer(int port) {
|
absl::StatusOr<int> ConnectToServer(int port) {
|
||||||
SAPI_ASSIGN_OR_RETURN(struct sockaddr_in6 saddr, CreateAddres(port));
|
SAPI_ASSIGN_OR_RETURN(struct sockaddr_in6 saddr, CreateAddres(port));
|
||||||
|
|
||||||
sandbox2::file_util::fileops::FDCloser s(socket(AF_INET6, SOCK_STREAM, 0));
|
sandbox2::file_util::fileops::FDCloser s(socket(AF_INET6, SOCK_STREAM, 0));
|
||||||
|
@ -134,7 +135,7 @@ int main(int argc, char** argv) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<int> sock_s = ConnectToServer(port);
|
absl::StatusOr<int> sock_s = ConnectToServer(port);
|
||||||
if (!sock_s.ok()) {
|
if (!sock_s.ok()) {
|
||||||
LOG(ERROR) << sock_s.status().message();
|
LOG(ERROR) << sock_s.status().message();
|
||||||
return 3;
|
return 3;
|
||||||
|
|
|
@ -52,8 +52,10 @@ std::unique_ptr<sandbox2::Policy> GetPolicy() {
|
||||||
// Allow the getpid() syscall.
|
// Allow the getpid() syscall.
|
||||||
.AllowSyscall(__NR_getpid)
|
.AllowSyscall(__NR_getpid)
|
||||||
|
|
||||||
|
#ifdef __NR_access
|
||||||
// On Debian, even static binaries check existence of /etc/ld.so.nohwcap.
|
// On Debian, even static binaries check existence of /etc/ld.so.nohwcap.
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Examples for AddPolicyOnSyscall:
|
// Examples for AddPolicyOnSyscall:
|
||||||
.AddPolicyOnSyscall(__NR_write,
|
.AddPolicyOnSyscall(__NR_write,
|
||||||
|
|
|
@ -86,7 +86,7 @@ pid_t Executor::StartSubProcess(int32_t clone_flags, const Namespace* ns,
|
||||||
if (!path_.empty()) {
|
if (!path_.empty()) {
|
||||||
exec_fd_ = open(path_.c_str(), O_PATH);
|
exec_fd_ = open(path_.c_str(), O_PATH);
|
||||||
if (exec_fd_ < 0) {
|
if (exec_fd_ < 0) {
|
||||||
LOG(ERROR) << "Could not open file " << path_;
|
PLOG(ERROR) << "Could not open file " << path_;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
|
@ -55,7 +56,6 @@
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
#include "sandboxed_api/util/raw_logging.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// "Moves" the old FD to the new FD number.
|
// "Moves" the old FD to the new FD number.
|
||||||
|
@ -142,7 +142,7 @@ absl::Status SendPid(int signaling_fd) {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<pid_t> ReceivePid(int signaling_fd) {
|
absl::StatusOr<pid_t> ReceivePid(int signaling_fd) {
|
||||||
union {
|
union {
|
||||||
struct cmsghdr cmh;
|
struct cmsghdr cmh;
|
||||||
char ctrl[CMSG_SPACE(sizeof(struct ucred))];
|
char ctrl[CMSG_SPACE(sizeof(struct ucred))];
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "absl/time/time.h"
|
#include "absl/time/time.h"
|
||||||
#include "sandboxed_api/sandbox2/client.h"
|
#include "sandboxed_api/sandbox2/client.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/limits.h"
|
#include "sandboxed_api/sandbox2/limits.h"
|
||||||
#include "sandboxed_api/sandbox2/mounts.h"
|
#include "sandboxed_api/sandbox2/mounts.h"
|
||||||
|
@ -761,7 +762,7 @@ void Monitor::LogSyscallViolation(const Syscall& syscall) const {
|
||||||
void Monitor::EventPtraceSeccomp(pid_t pid, int event_msg) {
|
void Monitor::EventPtraceSeccomp(pid_t pid, int event_msg) {
|
||||||
// If the seccomp-policy is using RET_TRACE, we request that it returns the
|
// If the seccomp-policy is using RET_TRACE, we request that it returns the
|
||||||
// syscall architecture identifier in the SECCOMP_RET_DATA.
|
// syscall architecture identifier in the SECCOMP_RET_DATA.
|
||||||
const auto syscall_arch = static_cast<Syscall::CpuArch>(event_msg);
|
const auto syscall_arch = static_cast<cpu::Architecture>(event_msg);
|
||||||
Regs regs(pid);
|
Regs regs(pid);
|
||||||
auto status = regs.Fetch();
|
auto status = regs.Fetch();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
|
|
|
@ -27,19 +27,20 @@
|
||||||
|
|
||||||
#include "google/protobuf/util/message_differencer.h"
|
#include "google/protobuf/util/message_differencer.h"
|
||||||
#include "absl/container/flat_hash_set.h"
|
#include "absl/container/flat_hash_set.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/ascii.h"
|
#include "absl/strings/ascii.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_join.h"
|
#include "absl/strings/str_join.h"
|
||||||
#include "absl/strings/str_split.h"
|
#include "absl/strings/str_split.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/minielf.h"
|
#include "sandboxed_api/sandbox2/util/minielf.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
#include "sandboxed_api/util/raw_logging.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -97,7 +98,7 @@ absl::string_view GetOutsidePath(const MountTree::Node& node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> ExistingPathInsideDir(
|
absl::StatusOr<std::string> ExistingPathInsideDir(
|
||||||
absl::string_view dir_path, absl::string_view relative_path) {
|
absl::string_view dir_path, absl::string_view relative_path) {
|
||||||
auto path = file::CleanPath(file::JoinPath(dir_path, relative_path));
|
auto path = file::CleanPath(file::JoinPath(dir_path, relative_path));
|
||||||
if (file_util::fileops::StripBasename(path) != dir_path) {
|
if (file_util::fileops::StripBasename(path) != dir_path) {
|
||||||
|
@ -112,6 +113,8 @@ sapi::StatusOr<std::string> ExistingPathInsideDir(
|
||||||
absl::Status ValidateInterpreter(absl::string_view interpreter) {
|
absl::Status ValidateInterpreter(absl::string_view interpreter) {
|
||||||
const absl::flat_hash_set<std::string> allowed_interpreters = {
|
const absl::flat_hash_set<std::string> allowed_interpreters = {
|
||||||
"/lib64/ld-linux-x86-64.so.2",
|
"/lib64/ld-linux-x86-64.so.2",
|
||||||
|
"/lib64/ld64.so.2", // PPC64
|
||||||
|
"/lib/ld-linux-aarch64.so.1", // AArch64
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!allowed_interpreters.contains(interpreter)) {
|
if (!allowed_interpreters.contains(interpreter)) {
|
||||||
|
@ -132,15 +135,21 @@ std::string ResolveLibraryPath(absl::string_view lib_name,
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr absl::string_view GetPlatformCPUName() {
|
||||||
|
switch (host_cpu::Architecture()) {
|
||||||
|
case cpu::kX8664:
|
||||||
|
return "x86_64";
|
||||||
|
case cpu::kPPC64LE:
|
||||||
|
return "ppc64";
|
||||||
|
case cpu::kArm64:
|
||||||
|
return "aarch64";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetPlatform(absl::string_view interpreter) {
|
std::string GetPlatform(absl::string_view interpreter) {
|
||||||
#if defined(__x86_64__)
|
return absl::StrCat(GetPlatformCPUName(), "-linux-gnu");
|
||||||
constexpr absl::string_view kCpuPlatform = "x86_64";
|
|
||||||
#elif defined(__powerpc64__)
|
|
||||||
constexpr absl::string_view kCpuPlatform = "ppc64";
|
|
||||||
#else
|
|
||||||
constexpr absl::string_view kCpuPlatform = "unknown";
|
|
||||||
#endif
|
|
||||||
return absl::StrCat(kCpuPlatform, "-linux-gnu");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -496,7 +505,7 @@ std::string MountFlagsToString(uint64_t flags) {
|
||||||
SAPI_MAP(MS_POSIXACL),
|
SAPI_MAP(MS_POSIXACL),
|
||||||
SAPI_MAP(MS_UNBINDABLE),
|
SAPI_MAP(MS_UNBINDABLE),
|
||||||
SAPI_MAP(MS_PRIVATE),
|
SAPI_MAP(MS_PRIVATE),
|
||||||
SAPI_MAP(MS_SLAVE),
|
SAPI_MAP(MS_SLAVE), // Inclusive language: system constant
|
||||||
SAPI_MAP(MS_SHARED),
|
SAPI_MAP(MS_SHARED),
|
||||||
SAPI_MAP(MS_RELATIME),
|
SAPI_MAP(MS_RELATIME),
|
||||||
SAPI_MAP(MS_KERNMOUNT),
|
SAPI_MAP(MS_KERNMOUNT),
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "absl/strings/numbers.h"
|
#include "absl/strings/numbers.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
|
@ -30,6 +30,7 @@ cc_library(
|
||||||
"//sandboxed_api/sandbox2:comms",
|
"//sandboxed_api/sandbox2:comms",
|
||||||
"//sandboxed_api/sandbox2/util:fileops",
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_glog//:glog",
|
"@com_google_glog//:glog",
|
||||||
],
|
],
|
||||||
|
@ -43,9 +44,11 @@ cc_library(
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//sandboxed_api/sandbox2:comms",
|
"//sandboxed_api/sandbox2:comms",
|
||||||
|
"//sandboxed_api/sandbox2:config",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
|
"@com_google_absl//absl/status",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/synchronization",
|
"@com_google_absl//absl/synchronization",
|
||||||
"@com_google_glog//:glog",
|
"@com_google_glog//:glog",
|
||||||
|
@ -61,7 +64,8 @@ cc_library(
|
||||||
"//sandboxed_api/sandbox2:comms",
|
"//sandboxed_api/sandbox2:comms",
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:statusor",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_glog//:glog",
|
"@com_google_glog//:glog",
|
||||||
],
|
],
|
||||||
|
|
|
@ -33,14 +33,14 @@ add_library(sandbox2_network_proxy_filtering STATIC
|
||||||
filtering.h
|
filtering.h
|
||||||
)
|
)
|
||||||
add_library(sandbox2::network_proxy_filtering ALIAS sandbox2_network_proxy_filtering)
|
add_library(sandbox2::network_proxy_filtering ALIAS sandbox2_network_proxy_filtering)
|
||||||
target_link_libraries(sandbox2_network_proxy_filtering PRIVATE
|
target_link_libraries(sandbox2_network_proxy_filtering
|
||||||
absl::memory
|
PRIVATE absl::memory
|
||||||
glog::glog
|
absl::status
|
||||||
sandbox2::comms
|
glog::glog
|
||||||
sandbox2::fileops
|
sandbox2::comms
|
||||||
sapi::base
|
sandbox2::fileops
|
||||||
|
sapi::base
|
||||||
PUBLIC sapi::status
|
PUBLIC sapi::status
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2/network_proxy:client
|
# sandboxed_api/sandbox2/network_proxy:client
|
||||||
|
@ -54,6 +54,7 @@ target_link_libraries(sandbox2_network_proxy_client PRIVATE
|
||||||
absl::synchronization
|
absl::synchronization
|
||||||
glog::glog
|
glog::glog
|
||||||
sandbox2::comms
|
sandbox2::comms
|
||||||
|
sandbox2::config
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::status
|
sapi::status
|
||||||
|
|
|
@ -25,9 +25,10 @@
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/status.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
@ -36,23 +37,26 @@ namespace sandbox2 {
|
||||||
constexpr int SYS_SECCOMP = 1;
|
constexpr int SYS_SECCOMP = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
constexpr int kRegResult = REG_RAX;
|
constexpr int kRegResult = REG_RAX;
|
||||||
constexpr int kRegSyscall = REG_RAX;
|
constexpr int kRegSyscall = REG_RAX;
|
||||||
constexpr int kRegArg0 = REG_RDI;
|
constexpr int kRegArg0 = REG_RDI;
|
||||||
constexpr int kRegArg1 = REG_RSI;
|
constexpr int kRegArg1 = REG_RSI;
|
||||||
constexpr int kRegArg2 = REG_RDX;
|
constexpr int kRegArg2 = REG_RDX;
|
||||||
#endif
|
#elif defined(SAPI_PPC64_LE)
|
||||||
#if defined(__powerpc64__)
|
|
||||||
constexpr int kRegResult = 3;
|
constexpr int kRegResult = 3;
|
||||||
constexpr int kRegSyscall = 0;
|
constexpr int kRegSyscall = 0;
|
||||||
constexpr int kRegArg0 = 3;
|
constexpr int kRegArg0 = 3;
|
||||||
constexpr int kRegArg1 = 4;
|
constexpr int kRegArg1 = 4;
|
||||||
constexpr int kRegArg2 = 5;
|
constexpr int kRegArg2 = 5;
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
constexpr int kRegResult = 0;
|
||||||
|
constexpr int kRegSyscall = 8;
|
||||||
|
constexpr int kRegArg0 = 0;
|
||||||
|
constexpr int kRegArg1 = 1;
|
||||||
|
constexpr int kRegArg2 = 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr char NetworkProxyClient::kFDName[];
|
|
||||||
|
|
||||||
int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr,
|
int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr,
|
||||||
socklen_t addrlen) {
|
socklen_t addrlen) {
|
||||||
absl::Status status = Connect(sockfd, addr, addrlen);
|
absl::Status status = Connect(sockfd, addr, addrlen);
|
||||||
|
@ -154,20 +158,22 @@ void NetworkProxyHandler::InvokeOldAct(int nr, siginfo_t* info,
|
||||||
|
|
||||||
void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
||||||
void* void_context) {
|
void* void_context) {
|
||||||
ucontext_t* ctx = (ucontext_t*)(void_context);
|
|
||||||
if (info->si_code != SYS_SECCOMP) {
|
if (info->si_code != SYS_SECCOMP) {
|
||||||
InvokeOldAct(nr, info, void_context);
|
InvokeOldAct(nr, info, void_context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ctx) return;
|
auto* ctx = static_cast<ucontext_t*>(void_context);
|
||||||
|
if (!ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
auto* registers = ctx->uc_mcontext.gregs;
|
auto* registers = ctx->uc_mcontext.gregs;
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
auto* registers = ctx->uc_mcontext.gp_regs;
|
auto* registers = ctx->uc_mcontext.gp_regs;
|
||||||
using ppc_gpreg_t = std::decay<decltype(registers[0])>::type;
|
#elif defined(SAPI_ARM64)
|
||||||
|
auto* registers = ctx->uc_mcontext.regs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int syscall = registers[kRegSyscall];
|
int syscall = registers[kRegSyscall];
|
||||||
|
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
@ -178,14 +184,13 @@ void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
||||||
sockfd = static_cast<int>(registers[kRegArg0]);
|
sockfd = static_cast<int>(registers[kRegArg0]);
|
||||||
addr = reinterpret_cast<const struct sockaddr*>(registers[kRegArg1]);
|
addr = reinterpret_cast<const struct sockaddr*>(registers[kRegArg1]);
|
||||||
addrlen = static_cast<socklen_t>(registers[kRegArg2]);
|
addrlen = static_cast<socklen_t>(registers[kRegArg2]);
|
||||||
#if defined(__powerpc64__)
|
#if defined(SAPI_PPC64_LE)
|
||||||
} else if (syscall == __NR_socketcall &&
|
} else if (syscall == __NR_socketcall &&
|
||||||
static_cast<int>(registers[kRegArg0]) == SYS_CONNECT) {
|
static_cast<int>(registers[kRegArg0]) == SYS_CONNECT) {
|
||||||
ppc_gpreg_t* args = reinterpret_cast<ppc_gpreg_t*>(registers[kRegArg1]);
|
auto* connect_args = reinterpret_cast<uint64_t*>(registers[kRegArg1]);
|
||||||
|
sockfd = static_cast<int>(connect_args[0]);
|
||||||
sockfd = static_cast<int>(args[0]);
|
addr = reinterpret_cast<const struct sockaddr*>(connect_args[1]);
|
||||||
addr = reinterpret_cast<const struct sockaddr*>(args[1]);
|
addrlen = static_cast<socklen_t>(connect_args[2]);
|
||||||
addrlen = static_cast<socklen_t>(args[2]);
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
InvokeOldAct(nr, info, void_context);
|
InvokeOldAct(nr, info, void_context);
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include "absl/status/status.h"
|
||||||
#include "absl/synchronization/mutex.h"
|
#include "absl/synchronization/mutex.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,17 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/numbers.h"
|
#include "absl/strings/numbers.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_split.h"
|
#include "absl/strings/str_split.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
static sapi::StatusOr<std::string> Addr6ToString(
|
static absl::StatusOr<std::string> Addr6ToString(
|
||||||
const struct sockaddr_in6* saddr) {
|
const struct sockaddr_in6* saddr) {
|
||||||
char addr[INET6_ADDRSTRLEN];
|
char addr[INET6_ADDRSTRLEN];
|
||||||
int port = htons(saddr->sin6_port);
|
int port = htons(saddr->sin6_port);
|
||||||
|
@ -38,7 +39,7 @@ static sapi::StatusOr<std::string> Addr6ToString(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts sockaddr_in structure into a string IPv4 representation.
|
// Converts sockaddr_in structure into a string IPv4 representation.
|
||||||
static sapi::StatusOr<std::string> Addr4ToString(
|
static absl::StatusOr<std::string> Addr4ToString(
|
||||||
const struct sockaddr_in* saddr) {
|
const struct sockaddr_in* saddr) {
|
||||||
char addr[INET_ADDRSTRLEN];
|
char addr[INET_ADDRSTRLEN];
|
||||||
int port = htons(saddr->sin_port);
|
int port = htons(saddr->sin_port);
|
||||||
|
@ -50,7 +51,7 @@ static sapi::StatusOr<std::string> Addr4ToString(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts sockaddr_in6 structure into a string IPv6 representation.
|
// Converts sockaddr_in6 structure into a string IPv6 representation.
|
||||||
sapi::StatusOr<std::string> AddrToString(const struct sockaddr* saddr) {
|
absl::StatusOr<std::string> AddrToString(const struct sockaddr* saddr) {
|
||||||
switch (saddr->sa_family) {
|
switch (saddr->sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
return Addr4ToString(reinterpret_cast<const struct sockaddr_in*>(saddr));
|
return Addr4ToString(reinterpret_cast<const struct sockaddr_in*>(saddr));
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
// Converts sockaddr_in or sockaddr_in6 structure into a string
|
// Converts sockaddr_in or sockaddr_in6 structure into a string
|
||||||
// representation.
|
// representation.
|
||||||
sapi::StatusOr<std::string> AddrToString(const struct sockaddr* saddr);
|
absl::StatusOr<std::string> AddrToString(const struct sockaddr* saddr);
|
||||||
|
|
||||||
struct IPv4 {
|
struct IPv4 {
|
||||||
in_addr_t ip;
|
in_addr_t ip;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
@ -104,7 +105,7 @@ void NetworkProxyServer::NotifySuccess() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkProxyServer::NotifyViolation(const struct sockaddr* saddr) {
|
void NetworkProxyServer::NotifyViolation(const struct sockaddr* saddr) {
|
||||||
if (sapi::StatusOr<std::string> result = AddrToString(saddr); result.ok()) {
|
if (absl::StatusOr<std::string> result = AddrToString(saddr); result.ok()) {
|
||||||
violation_msg_ = std::move(result).value();
|
violation_msg_ = std::move(result).value();
|
||||||
} else {
|
} else {
|
||||||
violation_msg_ = std::string(result.status().message());
|
violation_msg_ = std::string(result.status().message());
|
||||||
|
|
|
@ -49,8 +49,12 @@ std::unique_ptr<Policy> NotifyTestcasePolicy() {
|
||||||
.AllowWrite()
|
.AllowWrite()
|
||||||
.AllowSyscall(__NR_close)
|
.AllowSyscall(__NR_close)
|
||||||
.AddPolicyOnSyscall(__NR_personality, {SANDBOX2_TRACE})
|
.AddPolicyOnSyscall(__NR_personality, {SANDBOX2_TRACE})
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
|
@ -82,41 +82,41 @@ std::vector<sock_filter> Policy::GetDefaultPolicy() const {
|
||||||
bpf_labels l = {0};
|
bpf_labels l = {0};
|
||||||
|
|
||||||
std::vector<sock_filter> policy = {
|
std::vector<sock_filter> policy = {
|
||||||
// If compiled arch is different than the runtime one, inform the Monitor.
|
// If compiled arch is different than the runtime one, inform the Monitor.
|
||||||
LOAD_ARCH,
|
LOAD_ARCH,
|
||||||
JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)),
|
JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)),
|
||||||
JEQ32(AUDIT_ARCH_X86_64, TRACE(Syscall::kX86_64)),
|
#if defined(SAPI_X86_64)
|
||||||
JEQ32(AUDIT_ARCH_I386, TRACE(Syscall::kX86_32)),
|
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)), // 32-bit sandboxee
|
||||||
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(Syscall::kPPC_64)),
|
#endif
|
||||||
TRACE(Syscall::kUnknown),
|
TRACE(cpu::kUnknown),
|
||||||
LABEL(&l, past_arch_check_l),
|
LABEL(&l, past_arch_check_l),
|
||||||
|
|
||||||
// After the policy is uploaded, forkserver will execve the sandboxee. We
|
// After the policy is uploaded, forkserver will execve the sandboxee. We
|
||||||
// need to allow this execve but not others. Since BPF does not have
|
// need to allow this execve but not others. Since BPF does not have
|
||||||
// state, we need to inform the Monitor to decide, and for that we use a
|
// state, we need to inform the Monitor to decide, and for that we use a
|
||||||
// magic value in syscall args 5. Note that this value is not supposed to
|
// magic value in syscall args 5. Note that this value is not supposed to
|
||||||
// be secret, but just an optimization so that the monitor is not
|
// be secret, but just an optimization so that the monitor is not
|
||||||
// triggered on every call to execveat.
|
// triggered on every call to execveat.
|
||||||
LOAD_SYSCALL_NR,
|
LOAD_SYSCALL_NR,
|
||||||
JNE32(__NR_execveat, JUMP(&l, past_execveat_l)),
|
JNE32(__NR_execveat, JUMP(&l, past_execveat_l)),
|
||||||
ARG_32(4),
|
ARG_32(4),
|
||||||
JNE32(AT_EMPTY_PATH, JUMP(&l, past_execveat_l)),
|
JNE32(AT_EMPTY_PATH, JUMP(&l, past_execveat_l)),
|
||||||
ARG_32(5),
|
ARG_32(5),
|
||||||
JNE32(internal::kExecveMagic, JUMP(&l, past_execveat_l)),
|
JNE32(internal::kExecveMagic, JUMP(&l, past_execveat_l)),
|
||||||
SANDBOX2_TRACE,
|
SANDBOX2_TRACE,
|
||||||
LABEL(&l, past_execveat_l),
|
LABEL(&l, past_execveat_l),
|
||||||
|
|
||||||
// Forbid some syscalls because unsafe or too risky.
|
// Forbid some syscalls because unsafe or too risky.
|
||||||
LOAD_SYSCALL_NR,
|
LOAD_SYSCALL_NR,
|
||||||
JEQ32(__NR_ptrace, DENY),
|
JEQ32(__NR_ptrace, DENY),
|
||||||
JEQ32(__NR_bpf, DENY),
|
JEQ32(__NR_bpf, DENY),
|
||||||
|
|
||||||
// Disallow clone with CLONE_UNTRACED flag.
|
// Disallow clone with CLONE_UNTRACED flag.
|
||||||
JNE32(__NR_clone, JUMP(&l, past_clone_untraced_l)),
|
JNE32(__NR_clone, JUMP(&l, past_clone_untraced_l)),
|
||||||
// Regardless of arch, we only care about the lower 32-bits of the flags.
|
// Regardless of arch, we only care about the lower 32-bits of the flags.
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
JA32(CLONE_UNTRACED, DENY),
|
JA32(CLONE_UNTRACED, DENY),
|
||||||
LABEL(&l, past_clone_untraced_l),
|
LABEL(&l, past_clone_untraced_l),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (bpf_resolve_jumps(&l, policy.data(), policy.size()) != 0) {
|
if (bpf_resolve_jumps(&l, policy.data(), policy.size()) != 0) {
|
||||||
|
@ -129,11 +129,16 @@ std::vector<sock_filter> Policy::GetDefaultPolicy() const {
|
||||||
|
|
||||||
std::vector<sock_filter> Policy::GetTrackingPolicy() const {
|
std::vector<sock_filter> Policy::GetTrackingPolicy() const {
|
||||||
return {
|
return {
|
||||||
LOAD_ARCH,
|
LOAD_ARCH,
|
||||||
JEQ32(AUDIT_ARCH_X86_64, TRACE(Syscall::kX86_64)),
|
#if defined(SAPI_X86_64)
|
||||||
JEQ32(AUDIT_ARCH_I386, TRACE(Syscall::kX86_32)),
|
JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)),
|
||||||
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(Syscall::kPPC_64)),
|
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)),
|
||||||
TRACE(Syscall::kUnknown),
|
#elif defined(SAPI_PPC64_LE)
|
||||||
|
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)),
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
JEQ32(AUDIT_ARCH_AARCH64, TRACE(cpu::kArm64)),
|
||||||
|
#endif
|
||||||
|
TRACE(cpu::kUnknown),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/limits.h"
|
#include "sandboxed_api/sandbox2/limits.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
@ -49,14 +50,21 @@ std::unique_ptr<Policy> PolicyTestcasePolicy() {
|
||||||
.AllowSyscall(__NR_close)
|
.AllowSyscall(__NR_close)
|
||||||
.AllowSyscall(__NR_getppid)
|
.AllowSyscall(__NR_getppid)
|
||||||
.AllowTCGETS()
|
.AllowTCGETS()
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef __NR_faccessat
|
||||||
|
.BlockSyscallWithErrno(__NR_faccessat, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#ifdef SAPI_X86_64
|
||||||
// Test that 32-bit syscalls from 64-bit are disallowed.
|
// Test that 32-bit syscalls from 64-bit are disallowed.
|
||||||
TEST(PolicyTest, AMD64Syscall32PolicyAllowed) {
|
TEST(PolicyTest, AMD64Syscall32PolicyAllowed) {
|
||||||
SKIP_SANITIZERS_AND_COVERAGE;
|
SKIP_SANITIZERS_AND_COVERAGE;
|
||||||
|
@ -72,7 +80,7 @@ TEST(PolicyTest, AMD64Syscall32PolicyAllowed) {
|
||||||
|
|
||||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||||
EXPECT_THAT(result.reason_code(), Eq(1)); // __NR_exit in 32-bit
|
EXPECT_THAT(result.reason_code(), Eq(1)); // __NR_exit in 32-bit
|
||||||
EXPECT_THAT(result.GetSyscallArch(), Eq(Syscall::kX86_32));
|
EXPECT_THAT(result.GetSyscallArch(), Eq(cpu::kX86));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that 32-bit syscalls from 64-bit for FS checks are disallowed.
|
// Test that 32-bit syscalls from 64-bit for FS checks are disallowed.
|
||||||
|
@ -90,9 +98,9 @@ TEST(PolicyTest, AMD64Syscall32FsAllowed) {
|
||||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||||
EXPECT_THAT(result.reason_code(),
|
EXPECT_THAT(result.reason_code(),
|
||||||
Eq(33)); // __NR_access in 32-bit
|
Eq(33)); // __NR_access in 32-bit
|
||||||
EXPECT_THAT(result.GetSyscallArch(), Eq(Syscall::kX86_32));
|
EXPECT_THAT(result.GetSyscallArch(), Eq(cpu::kX86));
|
||||||
}
|
}
|
||||||
#endif // defined(__x86_64__)
|
#endif
|
||||||
|
|
||||||
// Test that ptrace(2) is disallowed.
|
// Test that ptrace(2) is disallowed.
|
||||||
TEST(PolicyTest, PtraceDisallowed) {
|
TEST(PolicyTest, PtraceDisallowed) {
|
||||||
|
@ -161,7 +169,9 @@ std::unique_ptr<Policy> MinimalTestcasePolicy() {
|
||||||
.AllowStaticStartup()
|
.AllowStaticStartup()
|
||||||
.AllowExit()
|
.AllowExit()
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,8 +206,10 @@ TEST(MinimalTest, MinimalSharedBinaryWorks) {
|
||||||
.AllowOpen()
|
.AllowOpen()
|
||||||
.AllowExit()
|
.AllowExit()
|
||||||
.AllowMmap()
|
.AllowMmap()
|
||||||
|
#ifdef __NR_access
|
||||||
// New glibc accesses /etc/ld.so.preload
|
// New glibc accesses /etc/ld.so.preload
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
.AddLibrariesForBinary(path)
|
.AddLibrariesForBinary(path)
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
@ -222,7 +234,9 @@ TEST(MallocTest, SystemMallocWorks) {
|
||||||
.AllowSystemMalloc()
|
.AllowSystemMalloc()
|
||||||
.AllowExit()
|
.AllowExit()
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
||||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||||
|
@ -246,7 +260,9 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) {
|
||||||
|
|
||||||
auto policy =
|
auto policy =
|
||||||
PolicyBuilder()
|
PolicyBuilder()
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
.AllowStaticStartup()
|
.AllowStaticStartup()
|
||||||
.AllowTcMalloc()
|
.AllowTcMalloc()
|
||||||
|
@ -257,7 +273,9 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) {
|
||||||
.AddPolicyOnSyscalls({__NR_read, __NR_write}, {ERRNO(43)})
|
.AddPolicyOnSyscalls({__NR_read, __NR_write}, {ERRNO(43)})
|
||||||
.AddPolicyOnSyscall(__NR_umask, {DENY})
|
.AddPolicyOnSyscall(__NR_umask, {DENY})
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
||||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||||
|
|
|
@ -15,13 +15,7 @@
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
||||||
#include <asm/ioctls.h> // For TCGETS
|
#include <asm/ioctls.h> // For TCGETS
|
||||||
#if defined(__x86_64__)
|
#include <fcntl.h> // For the fcntl flags
|
||||||
#include <asm/prctl.h>
|
|
||||||
#endif
|
|
||||||
#if defined(__powerpc64__)
|
|
||||||
#include <asm/termbits.h> // On PPC, TCGETS macro needs termios
|
|
||||||
#endif
|
|
||||||
#include <fcntl.h> // For the fcntl flags
|
|
||||||
#include <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
#include <linux/net.h> // For SYS_CONNECT
|
#include <linux/net.h> // For SYS_CONNECT
|
||||||
#include <linux/random.h> // For GRND_NONBLOCK
|
#include <linux/random.h> // For GRND_NONBLOCK
|
||||||
|
@ -34,13 +28,21 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/escaping.h"
|
#include "absl/strings/escaping.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/namespace.h"
|
#include "sandboxed_api/sandbox2/namespace.h"
|
||||||
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
|
|
||||||
|
#if defined(SAPI_X86_64)
|
||||||
|
#include <asm/prctl.h>
|
||||||
|
#elif defined(SAPI_PPC64_LE)
|
||||||
|
#include <asm/termbits.h> // On PPC, TCGETS macro needs termios
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -510,7 +512,7 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
||||||
JEQ32(SIG_UNBLOCK, ALLOW),
|
JEQ32(SIG_UNBLOCK, ALLOW),
|
||||||
});
|
});
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#ifdef SAPI_X86_64
|
||||||
// The second argument is a pointer.
|
// The second argument is a pointer.
|
||||||
AddPolicyOnSyscall(__NR_arch_prctl, {
|
AddPolicyOnSyscall(__NR_arch_prctl, {
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
|
@ -518,7 +520,12 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if constexpr (host_cpu::IsArm64()) {
|
||||||
|
BlockSyscallWithErrno(__NR_readlinkat, ENOENT);
|
||||||
|
}
|
||||||
|
#ifdef __NR_readlink
|
||||||
BlockSyscallWithErrno(__NR_readlink, ENOENT);
|
BlockSyscallWithErrno(__NR_readlink, ENOENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -526,7 +533,11 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
||||||
PolicyBuilder& PolicyBuilder::AllowDynamicStartup() {
|
PolicyBuilder& PolicyBuilder::AllowDynamicStartup() {
|
||||||
AllowRead();
|
AllowRead();
|
||||||
AllowStat();
|
AllowStat();
|
||||||
AllowSyscalls({__NR_lseek, __NR_close, __NR_munmap});
|
AllowSyscalls({__NR_lseek,
|
||||||
|
#ifdef __NR__llseek
|
||||||
|
__NR__llseek, // Newer glibc on PPC
|
||||||
|
#endif
|
||||||
|
__NR_close, __NR_munmap});
|
||||||
AddPolicyOnSyscall(__NR_mprotect, {
|
AddPolicyOnSyscall(__NR_mprotect, {
|
||||||
ARG_32(2),
|
ARG_32(2),
|
||||||
JEQ32(PROT_READ, ALLOW),
|
JEQ32(PROT_READ, ALLOW),
|
||||||
|
@ -656,7 +667,7 @@ PolicyBuilder& PolicyBuilder::DangerDefaultAllowAll() {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> PolicyBuilder::ValidateAbsolutePath(
|
absl::StatusOr<std::string> PolicyBuilder::ValidateAbsolutePath(
|
||||||
absl::string_view path) {
|
absl::string_view path) {
|
||||||
if (!file::IsAbsolutePath(path)) {
|
if (!file::IsAbsolutePath(path)) {
|
||||||
return absl::InvalidArgumentError(
|
return absl::InvalidArgumentError(
|
||||||
|
@ -665,7 +676,7 @@ sapi::StatusOr<std::string> PolicyBuilder::ValidateAbsolutePath(
|
||||||
return ValidatePath(path);
|
return ValidatePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> PolicyBuilder::ValidatePath(
|
absl::StatusOr<std::string> PolicyBuilder::ValidatePath(
|
||||||
absl::string_view path) {
|
absl::string_view path) {
|
||||||
std::string fixed_path = file::CleanPath(path);
|
std::string fixed_path = file::CleanPath(path);
|
||||||
if (fixed_path != path) {
|
if (fixed_path != path) {
|
||||||
|
@ -686,7 +697,7 @@ std::vector<sock_filter> PolicyBuilder::ResolveBpfFunc(BpfFunc f) {
|
||||||
return policy;
|
return policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::unique_ptr<Policy>> PolicyBuilder::TryBuild() {
|
absl::StatusOr<std::unique_ptr<Policy>> PolicyBuilder::TryBuild() {
|
||||||
auto output = absl::WrapUnique(new Policy());
|
auto output = absl::WrapUnique(new Policy());
|
||||||
|
|
||||||
if (!last_status_.ok()) {
|
if (!last_status_.ok()) {
|
||||||
|
@ -879,7 +890,9 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyPolicy() {
|
||||||
AllowFutexOp(FUTEX_WAIT);
|
AllowFutexOp(FUTEX_WAIT);
|
||||||
AllowFutexOp(FUTEX_WAIT_BITSET);
|
AllowFutexOp(FUTEX_WAIT_BITSET);
|
||||||
AllowSyscalls({
|
AllowSyscalls({
|
||||||
|
#ifdef __NR_dup2
|
||||||
__NR_dup2,
|
__NR_dup2,
|
||||||
|
#endif
|
||||||
__NR_recvmsg,
|
__NR_recvmsg,
|
||||||
__NR_close,
|
__NR_close,
|
||||||
__NR_gettid,
|
__NR_gettid,
|
||||||
|
@ -899,7 +912,7 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyPolicy() {
|
||||||
LABEL(&labels, getsockopt_end),
|
LABEL(&labels, getsockopt_end),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
#if defined(__powerpc64__)
|
#ifdef SAPI_PPC64_LE
|
||||||
AddPolicyOnSyscall(__NR_socketcall, {
|
AddPolicyOnSyscall(__NR_socketcall, {
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
JEQ32(SYS_SOCKET, ALLOW),
|
JEQ32(SYS_SOCKET, ALLOW),
|
||||||
|
@ -925,7 +938,7 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyHandlerPolicy() {
|
||||||
});
|
});
|
||||||
|
|
||||||
AddPolicyOnSyscall(__NR_connect, {TRAP(0)});
|
AddPolicyOnSyscall(__NR_connect, {TRAP(0)});
|
||||||
#if defined(__powerpc64__)
|
#ifdef SAPI_PPC64_LE
|
||||||
AddPolicyOnSyscall(__NR_socketcall, {
|
AddPolicyOnSyscall(__NR_socketcall, {
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
JEQ32(SYS_CONNECT, TRAP(0)),
|
JEQ32(SYS_CONNECT, TRAP(0)),
|
||||||
|
|
|
@ -29,18 +29,16 @@
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "absl/base/macros.h"
|
#include "absl/base/macros.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "sandboxed_api/sandbox2/mounts.h"
|
#include "sandboxed_api/sandbox2/mounts.h"
|
||||||
#include "sandboxed_api/sandbox2/network_proxy/filtering.h"
|
#include "sandboxed_api/sandbox2/network_proxy/filtering.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
struct bpf_labels;
|
struct bpf_labels;
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
constexpr char kDefaultHostname[] = "sandbox2";
|
|
||||||
|
|
||||||
// PolicyBuilder is a helper class to simplify creation of policies. The builder
|
// PolicyBuilder is a helper class to simplify creation of policies. The builder
|
||||||
// uses fluent interface for convenience and increased readability of policies.
|
// uses fluent interface for convenience and increased readability of policies.
|
||||||
//
|
//
|
||||||
|
@ -91,6 +89,8 @@ constexpr char kDefaultHostname[] = "sandbox2";
|
||||||
// For a more complicated example, see examples/persistent/persistent_sandbox.cc
|
// For a more complicated example, see examples/persistent/persistent_sandbox.cc
|
||||||
class PolicyBuilder final {
|
class PolicyBuilder final {
|
||||||
public:
|
public:
|
||||||
|
static constexpr absl::string_view kDefaultHostname = "sandbox2";
|
||||||
|
|
||||||
using BpfInitializer = std::initializer_list<sock_filter>;
|
using BpfInitializer = std::initializer_list<sock_filter>;
|
||||||
using BpfFunc = const std::function<std::vector<sock_filter>(bpf_labels&)>&;
|
using BpfFunc = const std::function<std::vector<sock_filter>(bpf_labels&)>&;
|
||||||
using SyscallInitializer = std::initializer_list<unsigned int>;
|
using SyscallInitializer = std::initializer_list<unsigned int>;
|
||||||
|
@ -390,7 +390,7 @@ class PolicyBuilder final {
|
||||||
|
|
||||||
// Builds the policy returning a unique_ptr to it. This should only be called
|
// Builds the policy returning a unique_ptr to it. This should only be called
|
||||||
// once.
|
// once.
|
||||||
sapi::StatusOr<std::unique_ptr<Policy>> TryBuild();
|
absl::StatusOr<std::unique_ptr<Policy>> TryBuild();
|
||||||
|
|
||||||
// Builds the policy returning a unique_ptr to it. This should only be called
|
// Builds the policy returning a unique_ptr to it. This should only be called
|
||||||
// once.
|
// once.
|
||||||
|
@ -532,9 +532,9 @@ class PolicyBuilder final {
|
||||||
|
|
||||||
std::vector<sock_filter> ResolveBpfFunc(BpfFunc f);
|
std::vector<sock_filter> ResolveBpfFunc(BpfFunc f);
|
||||||
|
|
||||||
static sapi::StatusOr<std::string> ValidateAbsolutePath(
|
static absl::StatusOr<std::string> ValidateAbsolutePath(
|
||||||
absl::string_view path);
|
absl::string_view path);
|
||||||
static sapi::StatusOr<std::string> ValidatePath(absl::string_view path);
|
static absl::StatusOr<std::string> ValidatePath(absl::string_view path);
|
||||||
|
|
||||||
void StoreDescription(PolicyBuilderDescription* pb_description);
|
void StoreDescription(PolicyBuilderDescription* pb_description);
|
||||||
|
|
||||||
|
@ -542,7 +542,7 @@ class PolicyBuilder final {
|
||||||
bool use_namespaces_ = true;
|
bool use_namespaces_ = true;
|
||||||
bool requires_namespaces_ = false;
|
bool requires_namespaces_ = false;
|
||||||
bool allow_unrestricted_networking_ = false;
|
bool allow_unrestricted_networking_ = false;
|
||||||
std::string hostname_ = kDefaultHostname;
|
std::string hostname_ = std::string(kDefaultHostname);
|
||||||
|
|
||||||
bool collect_stacktrace_on_violation_ = true;
|
bool collect_stacktrace_on_violation_ = true;
|
||||||
bool collect_stacktrace_on_signal_ = true;
|
bool collect_stacktrace_on_signal_ = true;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_split.h"
|
#include "absl/strings/str_split.h"
|
||||||
|
@ -57,7 +58,7 @@ class PolicyBuilderPeer {
|
||||||
|
|
||||||
int policy_size() const { return builder_->user_policy_.size(); }
|
int policy_size() const { return builder_->user_policy_.size(); }
|
||||||
|
|
||||||
static sapi::StatusOr<std::string> ValidateAbsolutePath(
|
static absl::StatusOr<std::string> ValidateAbsolutePath(
|
||||||
absl::string_view path) {
|
absl::string_view path) {
|
||||||
return PolicyBuilder::ValidateAbsolutePath(path);
|
return PolicyBuilder::ValidateAbsolutePath(path);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +101,7 @@ TEST_F(PolicyBuilderTest, Testpolicy_size) {
|
||||||
builder.AllowSystemMalloc(); assert_increased();
|
builder.AllowSystemMalloc(); assert_increased();
|
||||||
builder.AllowSyscall(__NR_munmap); assert_same();
|
builder.AllowSyscall(__NR_munmap); assert_same();
|
||||||
builder.BlockSyscallWithErrno(__NR_munmap, 1); assert_same();
|
builder.BlockSyscallWithErrno(__NR_munmap, 1); assert_same();
|
||||||
builder.BlockSyscallWithErrno(__NR_open, 1);
|
builder.BlockSyscallWithErrno(__NR_openat, 1);
|
||||||
assert_increased();
|
assert_increased();
|
||||||
|
|
||||||
builder.AllowTCGETS(); assert_increased();
|
builder.AllowTCGETS(); assert_increased();
|
||||||
|
|
|
@ -23,65 +23,108 @@
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
|
#include "absl/base/macros.h"
|
||||||
|
#include "absl/status/status.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
absl::Status Regs::Fetch() {
|
#ifndef NT_ARM_SYSTEM_CALL
|
||||||
#if defined(__powerpc64__)
|
#define NT_ARM_SYSTEM_CALL 0x404
|
||||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
#endif
|
||||||
|
|
||||||
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
absl::Status Regs::Fetch() {
|
||||||
return absl::InternalError(absl::StrCat(
|
#ifdef SAPI_X86_64
|
||||||
"ptrace(PTRACE_GETREGSET, pid=", pid_, ") failed: ", StrError(errno)));
|
|
||||||
}
|
|
||||||
if (pt_iov.iov_len != sizeof(user_regs_)) {
|
|
||||||
return absl::InternalError(absl::StrCat(
|
|
||||||
"ptrace(PTRACE_GETREGSET, pid=", pid_,
|
|
||||||
") size returned: ", pt_iov.iov_len,
|
|
||||||
" different than sizeof(user_regs_): ", sizeof(user_regs_)));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) {
|
if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) {
|
||||||
return absl::InternalError(absl::StrCat("ptrace(PTRACE_GETREGS, pid=", pid_,
|
return absl::InternalError(absl::StrCat("ptrace(PTRACE_GETREGS, pid=", pid_,
|
||||||
") failed: ", StrError(errno)));
|
") failed: ", StrError(errno)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) {
|
||||||
|
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||||
|
|
||||||
|
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("ptrace(PTRACE_GETREGSET, pid=", pid_,
|
||||||
|
") failed: ", StrError(errno)));
|
||||||
|
}
|
||||||
|
if (pt_iov.iov_len != sizeof(user_regs_)) {
|
||||||
|
return absl::InternalError(absl::StrCat(
|
||||||
|
"ptrace(PTRACE_GETREGSET, pid=", pid_,
|
||||||
|
") size returned: ", pt_iov.iov_len,
|
||||||
|
" different than sizeof(user_regs_): ", sizeof(user_regs_)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// On AArch64, we are not done yet. Read the syscall number.
|
||||||
|
if constexpr (host_cpu::IsArm64()) {
|
||||||
|
iovec sys_iov = {&syscall_number_, sizeof(syscall_number_)};
|
||||||
|
|
||||||
|
if (ptrace(PTRACE_GETREGSET, pid_, NT_ARM_SYSTEM_CALL, &sys_iov) == -1L) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("ptrace(PTRACE_GETREGSET, pid=", pid_,
|
||||||
|
", NT_ARM_SYSTEM_CALL) failed: ", StrError(errno)));
|
||||||
|
}
|
||||||
|
if (sys_iov.iov_len != sizeof(syscall_number_)) {
|
||||||
|
return absl::InternalError(absl::StrCat(
|
||||||
|
"ptrace(PTRACE_GETREGSET, pid=", pid_,
|
||||||
|
", NT_ARM_SYSTEM_CALL) size returned: ", sys_iov.iov_len,
|
||||||
|
" different than sizeof(syscall_number_): ",
|
||||||
|
sizeof(syscall_number_)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Regs::Store() {
|
absl::Status Regs::Store() {
|
||||||
#if defined(__powerpc64__)
|
#ifdef SAPI_X86_64
|
||||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
|
||||||
|
|
||||||
if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
|
||||||
return absl::InternalError(absl::StrCat(
|
|
||||||
"ptrace(PTRACE_SETREGSET, pid=", pid_, ") failed: ", StrError(errno)));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (ptrace(PTRACE_SETREGS, pid_, 0, &user_regs_) == -1) {
|
if (ptrace(PTRACE_SETREGS, pid_, 0, &user_regs_) == -1) {
|
||||||
return absl::InternalError(absl::StrCat("ptrace(PTRACE_SETREGS, pid=", pid_,
|
return absl::InternalError(absl::StrCat("ptrace(PTRACE_SETREGS, pid=", pid_,
|
||||||
") failed: ", StrError(errno)));
|
") failed: ", StrError(errno)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) {
|
||||||
|
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||||
|
|
||||||
|
if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("ptrace(PTRACE_SETREGSET, pid=", pid_,
|
||||||
|
") failed: ", StrError(errno)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store syscall number on AArch64.
|
||||||
|
if constexpr (host_cpu::IsArm64()) {
|
||||||
|
iovec sys_iov = {&syscall_number_, sizeof(syscall_number_)};
|
||||||
|
|
||||||
|
if (ptrace(PTRACE_SETREGSET, pid_, NT_ARM_SYSTEM_CALL, &sys_iov) == -1L) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("ptrace(PTRACE_SETREGSET, pid=", pid_,
|
||||||
|
", NT_ARM_SYSTEM_CALL) failed: ", StrError(errno)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Regs::SkipSyscallReturnValue(uint64_t value) {
|
absl::Status Regs::SkipSyscallReturnValue(uint64_t value) {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
user_regs_.orig_rax = -1;
|
user_regs_.orig_rax = -1;
|
||||||
user_regs_.rax = value;
|
user_regs_.rax = value;
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
user_regs_.gpr[0] = -1;
|
user_regs_.gpr[0] = -1;
|
||||||
user_regs_.gpr[3] = value;
|
user_regs_.gpr[3] = value;
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
user_regs_.regs[0] = -1;
|
||||||
|
syscall_number_ = value;
|
||||||
#endif
|
#endif
|
||||||
return Store();
|
return Store();
|
||||||
}
|
}
|
||||||
|
|
||||||
Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
Syscall Regs::ToSyscall(cpu::Architecture syscall_arch) const {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
if (ABSL_PREDICT_TRUE(syscall_arch == Syscall::kX86_64)) {
|
if (ABSL_PREDICT_TRUE(syscall_arch == cpu::kX8664)) {
|
||||||
auto syscall = user_regs_.orig_rax;
|
auto syscall = user_regs_.orig_rax;
|
||||||
Syscall::Args args = {user_regs_.rdi, user_regs_.rsi, user_regs_.rdx,
|
Syscall::Args args = {user_regs_.rdi, user_regs_.rsi, user_regs_.rdx,
|
||||||
user_regs_.r10, user_regs_.r8, user_regs_.r9};
|
user_regs_.r10, user_regs_.r8, user_regs_.r9};
|
||||||
|
@ -89,7 +132,7 @@ Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
||||||
auto ip = user_regs_.rip;
|
auto ip = user_regs_.rip;
|
||||||
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
||||||
}
|
}
|
||||||
if (syscall_arch == Syscall::kX86_32) {
|
if (syscall_arch == cpu::kX86) {
|
||||||
auto syscall = user_regs_.orig_rax & 0xFFFFFFFF;
|
auto syscall = user_regs_.orig_rax & 0xFFFFFFFF;
|
||||||
Syscall::Args args = {
|
Syscall::Args args = {
|
||||||
user_regs_.rbx & 0xFFFFFFFF, user_regs_.rcx & 0xFFFFFFFF,
|
user_regs_.rbx & 0xFFFFFFFF, user_regs_.rcx & 0xFFFFFFFF,
|
||||||
|
@ -99,8 +142,8 @@ Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
||||||
auto ip = user_regs_.rip & 0xFFFFFFFF;
|
auto ip = user_regs_.rip & 0xFFFFFFFF;
|
||||||
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
||||||
}
|
}
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
if (ABSL_PREDICT_TRUE(syscall_arch == Syscall::kPPC_64)) {
|
if (ABSL_PREDICT_TRUE(syscall_arch == cpu::kPPC64LE)) {
|
||||||
auto syscall = user_regs_.gpr[0];
|
auto syscall = user_regs_.gpr[0];
|
||||||
Syscall::Args args = {user_regs_.orig_gpr3, user_regs_.gpr[4],
|
Syscall::Args args = {user_regs_.orig_gpr3, user_regs_.gpr[4],
|
||||||
user_regs_.gpr[5], user_regs_.gpr[6],
|
user_regs_.gpr[5], user_regs_.gpr[6],
|
||||||
|
@ -109,12 +152,28 @@ Syscall Regs::ToSyscall(Syscall::CpuArch syscall_arch) const {
|
||||||
auto ip = user_regs_.nip;
|
auto ip = user_regs_.nip;
|
||||||
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
||||||
}
|
}
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
if (ABSL_PREDICT_TRUE(syscall_arch == cpu::kArm64)) {
|
||||||
|
Syscall::Args args = {
|
||||||
|
// First argument should be orig_x0, which is not available to ptrace on
|
||||||
|
// AArch64 (see
|
||||||
|
// https://undo.io/resources/arm64-vs-arm32-whats-different-linux-programmers/),
|
||||||
|
// as it will have been overwritten. For our use case, though, using
|
||||||
|
// regs[0] is fine, as we are always called on syscall entry and never
|
||||||
|
// on exit.
|
||||||
|
user_regs_.regs[0], user_regs_.regs[1], user_regs_.regs[2],
|
||||||
|
user_regs_.regs[3], user_regs_.regs[4], user_regs_.regs[5],
|
||||||
|
};
|
||||||
|
auto sp = user_regs_.sp;
|
||||||
|
auto ip = user_regs_.pc;
|
||||||
|
return Syscall(syscall_arch, syscall_number_, args, pid_, sp, ip);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return Syscall(pid_);
|
return Syscall(pid_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
RegisterX8664* regs = values->mutable_register_x86_64();
|
RegisterX8664* regs = values->mutable_register_x86_64();
|
||||||
regs->set_r15(user_regs_.r15);
|
regs->set_r15(user_regs_.r15);
|
||||||
regs->set_r14(user_regs_.r14);
|
regs->set_r14(user_regs_.r14);
|
||||||
|
@ -143,7 +202,7 @@ void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
||||||
regs->set_es(user_regs_.es);
|
regs->set_es(user_regs_.es);
|
||||||
regs->set_fs(user_regs_.fs);
|
regs->set_fs(user_regs_.fs);
|
||||||
regs->set_gs(user_regs_.gs);
|
regs->set_gs(user_regs_.gs);
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
RegisterPowerpc64* regs = values->mutable_register_powerpc64();
|
RegisterPowerpc64* regs = values->mutable_register_powerpc64();
|
||||||
for (int i = 0; i < ABSL_ARRAYSIZE(user_regs_.gpr); ++i) {
|
for (int i = 0; i < ABSL_ARRAYSIZE(user_regs_.gpr); ++i) {
|
||||||
regs->add_gpr(user_regs_.gpr[i]);
|
regs->add_gpr(user_regs_.gpr[i]);
|
||||||
|
@ -164,6 +223,14 @@ void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
||||||
regs->set_zero1(user_regs_.zero1);
|
regs->set_zero1(user_regs_.zero1);
|
||||||
regs->set_zero2(user_regs_.zero2);
|
regs->set_zero2(user_regs_.zero2);
|
||||||
regs->set_zero3(user_regs_.zero3);
|
regs->set_zero3(user_regs_.zero3);
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
RegisterAarch64* regs = values->mutable_register_aarch64();
|
||||||
|
for (int i = 0; i < ABSL_ARRAYSIZE(user_regs_.regs); ++i) {
|
||||||
|
regs->add_regs(user_regs_.regs[i]);
|
||||||
|
}
|
||||||
|
regs->set_sp(user_regs_.sp);
|
||||||
|
regs->set_pc(user_regs_.pc);
|
||||||
|
regs->set_pstate(user_regs_.pstate);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
#include "sandboxed_api/sandbox2/violation.pb.h"
|
#include "sandboxed_api/sandbox2/violation.pb.h"
|
||||||
|
|
||||||
|
@ -33,10 +34,6 @@ namespace sandbox2 {
|
||||||
// assumes the process is already attached.
|
// assumes the process is already attached.
|
||||||
class Regs {
|
class Regs {
|
||||||
public:
|
public:
|
||||||
#if !defined(__x86_64__) && !defined(__powerpc64__)
|
|
||||||
static_assert(false, "No support for the current CPU architecture");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
explicit Regs(pid_t pid) : pid_(pid) {}
|
explicit Regs(pid_t pid) : pid_(pid) {}
|
||||||
|
|
||||||
// Copies register values from the process
|
// Copies register values from the process
|
||||||
|
@ -49,7 +46,7 @@ class Regs {
|
||||||
absl::Status SkipSyscallReturnValue(uint64_t value);
|
absl::Status SkipSyscallReturnValue(uint64_t value);
|
||||||
|
|
||||||
// Converts raw register values obtained on syscall entry to syscall info
|
// Converts raw register values obtained on syscall entry to syscall info
|
||||||
Syscall ToSyscall(Syscall::CpuArch syscall_arch) const;
|
Syscall ToSyscall(cpu::Architecture syscall_arch) const;
|
||||||
|
|
||||||
pid_t pid() const { return pid_; }
|
pid_t pid() const { return pid_; }
|
||||||
|
|
||||||
|
@ -60,7 +57,7 @@ class Regs {
|
||||||
friend class StackTracePeer;
|
friend class StackTracePeer;
|
||||||
|
|
||||||
struct PtraceRegisters {
|
struct PtraceRegisters {
|
||||||
#if defined(__x86_64__)
|
#if defined(SAPI_X86_64)
|
||||||
uint64_t r15;
|
uint64_t r15;
|
||||||
uint64_t r14;
|
uint64_t r14;
|
||||||
uint64_t r13;
|
uint64_t r13;
|
||||||
|
@ -88,7 +85,7 @@ class Regs {
|
||||||
uint64_t es;
|
uint64_t es;
|
||||||
uint64_t fs;
|
uint64_t fs;
|
||||||
uint64_t gs;
|
uint64_t gs;
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
uint64_t gpr[32];
|
uint64_t gpr[32];
|
||||||
uint64_t nip;
|
uint64_t nip;
|
||||||
uint64_t msr;
|
uint64_t msr;
|
||||||
|
@ -108,6 +105,13 @@ class Regs {
|
||||||
uint64_t zero1;
|
uint64_t zero1;
|
||||||
uint64_t zero2;
|
uint64_t zero2;
|
||||||
uint64_t zero3;
|
uint64_t zero3;
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
uint64_t regs[31];
|
||||||
|
uint64_t sp;
|
||||||
|
uint64_t pc;
|
||||||
|
uint64_t pstate;
|
||||||
|
#else
|
||||||
|
static_assert(false, "Host CPU architecture not supported, see config.h");
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,6 +120,9 @@ class Regs {
|
||||||
|
|
||||||
// Registers fetched with ptrace(PR_GETREGS/GETREGSET, pid).
|
// Registers fetched with ptrace(PR_GETREGS/GETREGSET, pid).
|
||||||
PtraceRegisters user_regs_ = {};
|
PtraceRegisters user_regs_ = {};
|
||||||
|
|
||||||
|
// On AArch64, obtaining the syscall number needs a specific call to ptrace()
|
||||||
|
int syscall_number_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sandbox2
|
} // namespace sandbox2
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/regs.h"
|
#include "sandboxed_api/sandbox2/regs.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
|
|
||||||
|
@ -131,8 +132,8 @@ class Result {
|
||||||
// Returns the current syscall architecture.
|
// Returns the current syscall architecture.
|
||||||
// Client architecture when final_status_ == VIOLATION, might be different
|
// Client architecture when final_status_ == VIOLATION, might be different
|
||||||
// from the host architecture (32-bit vs 64-bit syscalls).
|
// from the host architecture (32-bit vs 64-bit syscalls).
|
||||||
Syscall::CpuArch GetSyscallArch() const {
|
cpu::Architecture GetSyscallArch() const {
|
||||||
return syscall_ ? syscall_->arch() : Syscall::kUnknown;
|
return syscall_ ? syscall_->arch() : cpu::kUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> stack_trace() { return stack_trace_; }
|
const std::vector<std::string> stack_trace() { return stack_trace_; }
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/time/time.h"
|
#include "absl/time/time.h"
|
||||||
#include "sandboxed_api/sandbox2/monitor.h"
|
#include "sandboxed_api/sandbox2/monitor.h"
|
||||||
#include "sandboxed_api/sandbox2/result.h"
|
#include "sandboxed_api/sandbox2/result.h"
|
||||||
|
@ -33,7 +34,7 @@ Sandbox2::~Sandbox2() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<Result> Sandbox2::AwaitResultWithTimeout(
|
absl::StatusOr<Result> Sandbox2::AwaitResultWithTimeout(
|
||||||
absl::Duration timeout) {
|
absl::Duration timeout) {
|
||||||
CHECK(monitor_ != nullptr) << "Sandbox was not launched yet";
|
CHECK(monitor_ != nullptr) << "Sandbox was not launched yet";
|
||||||
CHECK(monitor_thread_ != nullptr) << "Sandbox was already waited on";
|
CHECK(monitor_thread_ != nullptr) << "Sandbox was already waited on";
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "absl/base/macros.h"
|
#include "absl/base/macros.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/ipc.h"
|
#include "sandboxed_api/sandbox2/ipc.h"
|
||||||
|
@ -33,7 +34,6 @@
|
||||||
#include "sandboxed_api/sandbox2/notify.h"
|
#include "sandboxed_api/sandbox2/notify.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/sandbox2/result.h"
|
#include "sandboxed_api/sandbox2/result.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ class Sandbox2 final {
|
||||||
// Waits for sandbox execution to finish within the timeout.
|
// Waits for sandbox execution to finish within the timeout.
|
||||||
// Returns execution result or a DeadlineExceededError if the sandboxee does
|
// Returns execution result or a DeadlineExceededError if the sandboxee does
|
||||||
// not finish in time.
|
// not finish in time.
|
||||||
sapi::StatusOr<Result> AwaitResultWithTimeout(absl::Duration timeout);
|
absl::StatusOr<Result> AwaitResultWithTimeout(absl::Duration timeout);
|
||||||
|
|
||||||
// Requests termination of the sandboxee.
|
// Requests termination of the sandboxee.
|
||||||
// Sandbox should still waited with AwaitResult(), as it may finish for other
|
// Sandbox should still waited with AwaitResult(), as it may finish for other
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/policy.h"
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "absl/strings/strip.h"
|
#include "absl/strings/strip.h"
|
||||||
#include "libcap/include/sys/capability.h"
|
#include "libcap/include/sys/capability.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/ipc.h"
|
#include "sandboxed_api/sandbox2/ipc.h"
|
||||||
#include "sandboxed_api/sandbox2/limits.h"
|
#include "sandboxed_api/sandbox2/limits.h"
|
||||||
|
@ -85,6 +86,9 @@ std::unique_ptr<Policy> StackTracePeer::GetPolicy(pid_t target_pid,
|
||||||
// libunwind
|
// libunwind
|
||||||
.AllowSyscall(__NR_fstat)
|
.AllowSyscall(__NR_fstat)
|
||||||
.AllowSyscall(__NR_lseek)
|
.AllowSyscall(__NR_lseek)
|
||||||
|
#ifdef __NR__llseek
|
||||||
|
.AllowSyscall(__NR__llseek) // Newer glibc on PPC
|
||||||
|
#endif
|
||||||
.AllowSyscall(__NR_mincore)
|
.AllowSyscall(__NR_mincore)
|
||||||
.AllowSyscall(__NR_mprotect)
|
.AllowSyscall(__NR_mprotect)
|
||||||
.AllowSyscall(__NR_munmap)
|
.AllowSyscall(__NR_munmap)
|
||||||
|
@ -270,6 +274,9 @@ bool StackTracePeer::LaunchLibunwindSandbox(const Regs* regs,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> GetStackTrace(const Regs* regs, const Mounts& mounts) {
|
std::vector<std::string> GetStackTrace(const Regs* regs, const Mounts& mounts) {
|
||||||
|
if constexpr (host_cpu::IsArm64()) {
|
||||||
|
return {"[Stack traces unavailable]"};
|
||||||
|
}
|
||||||
if (absl::GetFlag(FLAGS_sandbox_disable_all_stack_traces)) {
|
if (absl::GetFlag(FLAGS_sandbox_disable_all_stack_traces)) {
|
||||||
return {"[Stacktraces disabled]"};
|
return {"[Stacktraces disabled]"};
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,11 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// Implementation of the sandbox2::Syscall class.
|
|
||||||
|
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
|
|
||||||
#include <linux/audit.h>
|
#include <linux/audit.h>
|
||||||
#include <linux/elf-em.h>
|
#include <linux/elf-em.h>
|
||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -26,6 +25,7 @@
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/strings/str_join.h"
|
#include "absl/strings/str_join.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall_defs.h"
|
#include "sandboxed_api/sandbox2/syscall_defs.h"
|
||||||
|
|
||||||
#ifndef AUDIT_ARCH_PPC64LE
|
#ifndef AUDIT_ARCH_PPC64LE
|
||||||
|
@ -34,46 +34,43 @@
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
std::string Syscall::GetArchDescription(CpuArch arch) {
|
std::string Syscall::GetArchDescription(cpu::Architecture arch) {
|
||||||
switch (arch) {
|
switch (arch) {
|
||||||
case kX86_64:
|
case cpu::kX8664:
|
||||||
return "[X86-64]";
|
return "[X86-64]";
|
||||||
case kX86_32:
|
case cpu::kX86:
|
||||||
return "[X86-32]";
|
return "[X86-32]";
|
||||||
case kPPC_64:
|
case cpu::kPPC64LE:
|
||||||
return "[PPC-64]";
|
return "[PPC-64]";
|
||||||
|
case cpu::kArm64:
|
||||||
|
return "[Arm-64]";
|
||||||
default:
|
default:
|
||||||
LOG(ERROR) << "Unknown CPU architecture: " << arch;
|
LOG(ERROR) << "Unknown CPU architecture: " << arch;
|
||||||
return absl::StrFormat("[UNKNOWN_ARCH:%d]", arch);
|
return absl::StrFormat("[UNKNOWN_ARCH:%d]", arch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Syscall::CpuArch Syscall::GetHostArch() {
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
return kX86_64;
|
|
||||||
#elif defined(__i386__)
|
|
||||||
return kX86_32;
|
|
||||||
#elif defined(__powerpc64__)
|
|
||||||
return kPPC_64;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Syscall::GetHostAuditArch() {
|
uint32_t Syscall::GetHostAuditArch() {
|
||||||
#if defined(__x86_64__)
|
switch (host_cpu::Architecture()) {
|
||||||
return AUDIT_ARCH_X86_64;
|
case cpu::kX8664:
|
||||||
#elif defined(__i386__)
|
return AUDIT_ARCH_X86_64;
|
||||||
return AUDIT_ARCH_I386;
|
case cpu::kPPC64LE:
|
||||||
#elif defined(__powerpc64__)
|
return AUDIT_ARCH_PPC64LE;
|
||||||
return AUDIT_ARCH_PPC64LE;
|
case cpu::kArm64:
|
||||||
#endif
|
return AUDIT_ARCH_AARCH64;
|
||||||
|
default:
|
||||||
|
// The static_assert() in config.h should prevent us from ever getting
|
||||||
|
// here.
|
||||||
|
return 0; // Not reached
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Syscall::GetName() const {
|
std::string Syscall::GetName() const {
|
||||||
absl::string_view name = SyscallTable::get(arch_).GetName(nr_);
|
if (absl::string_view name = SyscallTable::get(arch_).GetName(nr_);
|
||||||
if (name.empty()) {
|
!name.empty()) {
|
||||||
return absl::StrFormat("UNKNOWN[%d/0x%x]", nr_, nr_);
|
return std::string(name);
|
||||||
}
|
}
|
||||||
return std::string(name);
|
return absl::StrFormat("UNKNOWN[%d/0x%x]", nr_, nr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> Syscall::GetArgumentsDescription() const {
|
std::vector<std::string> Syscall::GetArgumentsDescription() const {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// The sandbox2::Syscalls class defines mostly static helper methods which
|
// The sandbox2::Syscalls class defines mostly static helper methods which
|
||||||
// are used to analyze status of the ptraced process
|
// are used to analyze the status of the sandboxed process.
|
||||||
|
|
||||||
#ifndef SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
#ifndef SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
||||||
#define SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
#define SANDBOXED_API_SANDBOX2_SYSCALL_H__
|
||||||
|
@ -26,40 +26,34 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
class Syscall {
|
class Syscall {
|
||||||
public:
|
public:
|
||||||
// Supported CPU architectures.
|
|
||||||
// Linux: Use a magic value, so it can be easily spotted in the seccomp-bpf
|
|
||||||
// bytecode decompilation stream. Must be < (1<<15), as/ that's the size of
|
|
||||||
// data which can be returned by BPF.
|
|
||||||
enum CpuArch {
|
|
||||||
kUnknown = 0xCAF0,
|
|
||||||
kX86_64,
|
|
||||||
kX86_32,
|
|
||||||
kPPC_64,
|
|
||||||
};
|
|
||||||
// Maximum number of syscall arguments
|
// Maximum number of syscall arguments
|
||||||
static constexpr size_t kMaxArgs = 6;
|
static constexpr size_t kMaxArgs = 6;
|
||||||
using Args = std::array<uint64_t, kMaxArgs>;
|
using Args = std::array<uint64_t, kMaxArgs>;
|
||||||
|
|
||||||
// Returns the host architecture, according to CpuArch.
|
// Returns the host architecture, according to CpuArch.
|
||||||
static CpuArch GetHostArch();
|
static constexpr cpu::Architecture GetHostArch() {
|
||||||
|
return host_cpu::Architecture();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the host architecture, according to <linux/audit.h>.
|
// Returns the host architecture, according to <linux/audit.h>.
|
||||||
static uint32_t GetHostAuditArch();
|
static uint32_t GetHostAuditArch();
|
||||||
|
|
||||||
// Returns a description of the architecture.
|
// Returns a description of the architecture.
|
||||||
static std::string GetArchDescription(CpuArch arch);
|
static std::string GetArchDescription(cpu::Architecture arch);
|
||||||
|
|
||||||
Syscall() = default;
|
Syscall() = default;
|
||||||
Syscall(CpuArch arch, uint64_t nr, Args args = {})
|
Syscall(cpu::Architecture arch, uint64_t nr, Args args = {})
|
||||||
: arch_(arch), nr_(nr), args_(args) {}
|
: arch_(arch), nr_(nr), args_(args) {}
|
||||||
|
|
||||||
pid_t pid() const { return pid_; }
|
pid_t pid() const { return pid_; }
|
||||||
uint64_t nr() const { return nr_; }
|
uint64_t nr() const { return nr_; }
|
||||||
CpuArch arch() const { return arch_; }
|
cpu::Architecture arch() const { return arch_; }
|
||||||
const Args& args() const { return args_; }
|
const Args& args() const { return args_; }
|
||||||
uint64_t stack_pointer() const { return sp_; }
|
uint64_t stack_pointer() const { return sp_; }
|
||||||
uint64_t instruction_pointer() const { return ip_; }
|
uint64_t instruction_pointer() const { return ip_; }
|
||||||
|
@ -72,12 +66,12 @@ class Syscall {
|
||||||
private:
|
private:
|
||||||
friend class Regs;
|
friend class Regs;
|
||||||
|
|
||||||
Syscall(pid_t pid) : pid_(pid) {}
|
explicit Syscall(pid_t pid) : pid_(pid) {}
|
||||||
Syscall(CpuArch arch, uint64_t nr, Args args, pid_t pid, uint64_t sp,
|
Syscall(cpu::Architecture arch, uint64_t nr, Args args, pid_t pid,
|
||||||
uint64_t ip)
|
uint64_t sp, uint64_t ip)
|
||||||
: arch_(arch), nr_(nr), args_(args), pid_(pid), sp_(sp), ip_(ip) {}
|
: arch_(arch), nr_(nr), args_(args), pid_(pid), sp_(sp), ip_(ip) {}
|
||||||
|
|
||||||
CpuArch arch_ = kUnknown;
|
cpu::Architecture arch_ = cpu::kUnknown;
|
||||||
uint64_t nr_ = -1;
|
uint64_t nr_ = -1;
|
||||||
Args args_ = {};
|
Args args_ = {};
|
||||||
pid_t pid_ = -1;
|
pid_t pid_ = -1;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "absl/strings/escaping.h"
|
#include "absl/strings/escaping.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util.h"
|
#include "sandboxed_api/sandbox2/util.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
@ -128,7 +129,6 @@ std::vector<std::string> SyscallTable::GetArgumentsDescription(
|
||||||
#define SYSCALLS_UNUSED00_99(prefix) \
|
#define SYSCALLS_UNUSED00_99(prefix) \
|
||||||
SYSCALLS_UNUSED00_49(prefix), SYSCALLS_UNUSED50_99(prefix)
|
SYSCALLS_UNUSED00_49(prefix), SYSCALLS_UNUSED50_99(prefix)
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
// Syscall description table for Linux x86_64
|
// Syscall description table for Linux x86_64
|
||||||
constexpr SyscallTable::Entry kSyscallDataX8664[] = {
|
constexpr SyscallTable::Entry kSyscallDataX8664[] = {
|
||||||
MakeEntry("read", kInt, kHex, kInt), // 0
|
MakeEntry("read", kInt, kHex, kInt), // 0
|
||||||
|
@ -824,12 +824,10 @@ constexpr SyscallTable::Entry kSyscallDataX8632[] = {
|
||||||
MakeEntry("bpf", kHex, kHex, kHex, kHex, kHex, kHex), // 357
|
MakeEntry("bpf", kHex, kHex, kHex, kHex, kHex, kHex), // 357
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined(__powerpc64__)
|
|
||||||
|
|
||||||
// http://lxr.free-electrons.com/source/arch/powerpc/include/uapi/asm/unistd.h
|
// http://lxr.free-electrons.com/source/arch/powerpc/include/uapi/asm/unistd.h
|
||||||
// Note: PPC64 syscalls can have up to 7 register arguments, but nobody is
|
// Note: PPC64 syscalls can have up to 7 register arguments, but nobody is
|
||||||
// using the 7th argument - probably for x64 compatibility reasons.
|
// using the 7th argument - probably for x64 compatibility reasons.
|
||||||
constexpr SyscallTable::Entry kSyscallDataPPC64[] = {
|
constexpr SyscallTable::Entry kSyscallDataPPC64LE[] = {
|
||||||
MakeEntry("restart_syscall", kGen, kGen, kGen, kGen, kGen, kGen), // 0
|
MakeEntry("restart_syscall", kGen, kGen, kGen, kGen, kGen, kGen), // 0
|
||||||
MakeEntry("exit", kInt, kGen, kGen, kGen, kGen, kGen), // 1
|
MakeEntry("exit", kInt, kGen, kGen, kGen, kGen, kGen), // 1
|
||||||
MakeEntry("fork", kGen, kGen, kGen, kGen, kGen, kGen), // 2
|
MakeEntry("fork", kGen, kGen, kGen, kGen, kGen, kGen), // 2
|
||||||
|
@ -1218,7 +1216,290 @@ constexpr SyscallTable::Entry kSyscallDataPPC64[] = {
|
||||||
MakeEntry("pwritev2", kHex, kHex, kHex, kHex, kHex, kHex), // 381
|
MakeEntry("pwritev2", kHex, kHex, kHex, kHex, kHex, kHex), // 381
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
// TODO(cblichmann): Confirm the entries in this list.
|
||||||
|
// https://github.com/torvalds/linux/blob/v5.8/include/uapi/asm-generic/unistd.h
|
||||||
|
constexpr SyscallTable::Entry kSyscallDataArm64[] = {
|
||||||
|
MakeEntry("io_setup", UnknownArguments()), // 0
|
||||||
|
MakeEntry("io_destroy", UnknownArguments()), // 1
|
||||||
|
MakeEntry("io_submit", UnknownArguments()), // 2
|
||||||
|
MakeEntry("io_cancel", UnknownArguments()), // 3
|
||||||
|
MakeEntry("io_getevents", UnknownArguments()), // 4
|
||||||
|
MakeEntry("setxattr", kPath, kString, kGen, kInt, kHex, kGen), // 5
|
||||||
|
MakeEntry("lsetxattr", kPath, kString, kGen, kInt, kHex, kGen), // 6
|
||||||
|
MakeEntry("fsetxattr", UnknownArguments()), // 7
|
||||||
|
MakeEntry("getxattr", kPath, kString, kGen, kInt, kGen, kGen), // 8
|
||||||
|
MakeEntry("lgetxattr", kPath, kString, kGen, kInt, kGen, kGen), // 9
|
||||||
|
MakeEntry("fgetxattr", UnknownArguments()), // 10
|
||||||
|
MakeEntry("listxattr", kPath, kGen, kInt, kGen, kGen, kGen), // 11
|
||||||
|
MakeEntry("llistxattr", kPath, kGen, kInt, kGen, kGen, kGen), // 12
|
||||||
|
MakeEntry("flistxattr", UnknownArguments()), // 13
|
||||||
|
MakeEntry("removexattr", kPath, kString, kGen, kGen, kGen, kGen), // 14
|
||||||
|
MakeEntry("lremovexattr", UnknownArguments()), // 15
|
||||||
|
MakeEntry("fremovexattr", UnknownArguments()), // 16
|
||||||
|
MakeEntry("getcwd", UnknownArguments()), // 17
|
||||||
|
MakeEntry("lookup_dcookie", UnknownArguments()), // 18
|
||||||
|
MakeEntry("eventfd2", UnknownArguments()), // 19
|
||||||
|
MakeEntry("epoll_create1", UnknownArguments()), // 20
|
||||||
|
MakeEntry("epoll_ctl", UnknownArguments()), // 21
|
||||||
|
MakeEntry("epoll_pwait", UnknownArguments()), // 22
|
||||||
|
MakeEntry("dup", UnknownArguments()), // 23
|
||||||
|
MakeEntry("dup3", UnknownArguments()), // 24
|
||||||
|
MakeEntry("fcntl", UnknownArguments()), // 25
|
||||||
|
MakeEntry("inotify_init1", UnknownArguments()), // 26
|
||||||
|
MakeEntry("inotify_add_watch", UnknownArguments()), // 27
|
||||||
|
MakeEntry("inotify_rm_watch", UnknownArguments()), // 28
|
||||||
|
MakeEntry("ioctl", UnknownArguments()), // 29
|
||||||
|
MakeEntry("ioprio_set", UnknownArguments()), // 30
|
||||||
|
MakeEntry("ioprio_get", UnknownArguments()), // 31
|
||||||
|
MakeEntry("flock", UnknownArguments()), // 32
|
||||||
|
MakeEntry("mknodat", kGen, kPath, kGen, kGen, kGen, kGen), // 33
|
||||||
|
MakeEntry("mkdirat", kGen, kPath, kGen, kGen, kGen, kGen), // 34
|
||||||
|
MakeEntry("unlinkat", kGen, kPath, kGen, kGen, kGen, kGen), // 35
|
||||||
|
MakeEntry("symlinkat", kPath, kGen, kPath, kGen, kGen, kGen), // 36
|
||||||
|
MakeEntry("linkat", kGen, kPath, kGen, kPath, kGen, kGen), // 37
|
||||||
|
MakeEntry("renameat", kGen, kPath, kGen, kPath, kGen, kGen), // 38
|
||||||
|
MakeEntry("umount2", kPath, kHex, kGen, kGen, kGen, kGen), // 39
|
||||||
|
MakeEntry("mount", kPath, kPath, kString, kHex, kGen, kGen), // 40
|
||||||
|
MakeEntry("pivot_root", kPath, kPath, kGen, kGen, kGen, kGen), // 41
|
||||||
|
MakeEntry("nfsservctl", UnknownArguments()), // 42
|
||||||
|
MakeEntry("statfs", kPath, kGen, kGen, kGen, kGen, kGen), // 43
|
||||||
|
MakeEntry("fstatfs", UnknownArguments()), // 44
|
||||||
|
MakeEntry("truncate", kPath, kInt, kGen, kGen, kGen, kGen), // 45
|
||||||
|
MakeEntry("ftruncate", UnknownArguments()), // 46
|
||||||
|
MakeEntry("fallocate", UnknownArguments()), // 47
|
||||||
|
MakeEntry("faccessat", kGen, kPath, kGen, kGen, kGen, kGen), // 48
|
||||||
|
MakeEntry("chdir", kPath, kGen, kGen, kGen, kGen, kGen), // 49
|
||||||
|
MakeEntry("fchdir", UnknownArguments()), // 50
|
||||||
|
MakeEntry("chroot", kPath, kGen, kGen, kGen, kGen, kGen), // 51
|
||||||
|
MakeEntry("fchmod", UnknownArguments()), // 52
|
||||||
|
MakeEntry("fchmodat", kGen, kPath, kGen, kGen, kGen, kGen), // 53
|
||||||
|
MakeEntry("fchownat", kGen, kPath, kGen, kGen, kGen, kGen), // 54
|
||||||
|
MakeEntry("fchown", UnknownArguments()), // 55
|
||||||
|
MakeEntry("openat", kGen, kPath, kOct, kHex, kGen, kGen), // 56
|
||||||
|
MakeEntry("close", kInt, kGen, kGen, kGen, kGen, kGen), // 57
|
||||||
|
MakeEntry("vhangup", UnknownArguments()), // 58
|
||||||
|
MakeEntry("pipe2", UnknownArguments()), // 59
|
||||||
|
MakeEntry("quotactl", kInt, kPath, kInt, kGen, kGen, kGen), // 60
|
||||||
|
MakeEntry("getdents64", UnknownArguments()), // 61
|
||||||
|
MakeEntry("lseek", UnknownArguments()), // 62
|
||||||
|
MakeEntry("read", kInt, kHex, kInt, kGen, kGen, kGen), // 63
|
||||||
|
MakeEntry("write", kInt, kHex, kInt, kGen, kGen, kGen), // 64
|
||||||
|
MakeEntry("readv", UnknownArguments()), // 65
|
||||||
|
MakeEntry("writev", UnknownArguments()), // 66
|
||||||
|
MakeEntry("pread64", UnknownArguments()), // 67
|
||||||
|
MakeEntry("pwrite64", UnknownArguments()), // 68
|
||||||
|
MakeEntry("preadv", UnknownArguments()), // 69
|
||||||
|
MakeEntry("pwritev", UnknownArguments()), // 70
|
||||||
|
MakeEntry("sendfile", UnknownArguments()), // 71
|
||||||
|
MakeEntry("pselect6", UnknownArguments()), // 72
|
||||||
|
MakeEntry("ppoll", UnknownArguments()), // 73
|
||||||
|
MakeEntry("signalfd4", UnknownArguments()), // 74
|
||||||
|
MakeEntry("vmsplice", UnknownArguments()), // 75
|
||||||
|
MakeEntry("splice", UnknownArguments()), // 76
|
||||||
|
MakeEntry("tee", UnknownArguments()), // 77
|
||||||
|
MakeEntry("readlinkat", kGen, kPath, kGen, kGen, kGen, kGen), // 78
|
||||||
|
MakeEntry("newfstatat", kGen, kPath, kGen, kGen, kGen, kGen), // 79
|
||||||
|
MakeEntry("fstat", kInt, kHex, kGen, kGen, kGen, kGen), // 80
|
||||||
|
MakeEntry("sync", UnknownArguments()), // 81
|
||||||
|
MakeEntry("fsync", UnknownArguments()), // 82
|
||||||
|
MakeEntry("fdatasync", UnknownArguments()), // 83
|
||||||
|
MakeEntry("sync_file_range", UnknownArguments()), // 84
|
||||||
|
MakeEntry("timerfd_create", UnknownArguments()), // 85
|
||||||
|
MakeEntry("timerfd_settime", UnknownArguments()), // 86
|
||||||
|
MakeEntry("timerfd_gettime", UnknownArguments()), // 87
|
||||||
|
MakeEntry("utimensat", UnknownArguments()), // 88
|
||||||
|
MakeEntry("acct", kPath, kGen, kGen, kGen, kGen, kGen), // 89
|
||||||
|
MakeEntry("capget", UnknownArguments()), // 90
|
||||||
|
MakeEntry("capset", UnknownArguments()), // 91
|
||||||
|
MakeEntry("personality", UnknownArguments()), // 92
|
||||||
|
MakeEntry("exit", kInt, kGen, kGen, kGen, kGen, kGen), // 93
|
||||||
|
MakeEntry("exit_group", kInt, kGen, kGen, kGen, kGen, kGen), // 94
|
||||||
|
MakeEntry("waitid", UnknownArguments()), // 95
|
||||||
|
MakeEntry("set_tid_address", kHex, kGen, kGen, kGen, kGen, kGen), // 96
|
||||||
|
MakeEntry("unshare", UnknownArguments()), // 97
|
||||||
|
MakeEntry("futex", UnknownArguments()), // 98
|
||||||
|
MakeEntry("set_robust_list", UnknownArguments()), // 99
|
||||||
|
MakeEntry("get_robust_list", UnknownArguments()), // 100
|
||||||
|
MakeEntry("nanosleep", kHex, kHex, kGen, kGen, kGen, kGen), // 101
|
||||||
|
MakeEntry("getitimer", UnknownArguments()), // 102
|
||||||
|
MakeEntry("setitimer", UnknownArguments()), // 103
|
||||||
|
MakeEntry("kexec_load", UnknownArguments()), // 104
|
||||||
|
MakeEntry("init_module", UnknownArguments()), // 105
|
||||||
|
MakeEntry("delete_module", UnknownArguments()), // 106
|
||||||
|
MakeEntry("timer_create", UnknownArguments()), // 107
|
||||||
|
MakeEntry("timer_gettime", UnknownArguments()), // 108
|
||||||
|
MakeEntry("timer_getoverrun", UnknownArguments()), // 109
|
||||||
|
MakeEntry("timer_settime", UnknownArguments()), // 110
|
||||||
|
MakeEntry("timer_delete", UnknownArguments()), // 111
|
||||||
|
MakeEntry("clock_settime", UnknownArguments()), // 112
|
||||||
|
MakeEntry("clock_gettime", UnknownArguments()), // 113
|
||||||
|
MakeEntry("clock_getres", UnknownArguments()), // 114
|
||||||
|
MakeEntry("clock_nanosleep", UnknownArguments()), // 115
|
||||||
|
MakeEntry("syslog", UnknownArguments()), // 116
|
||||||
|
MakeEntry("ptrace", UnknownArguments()), // 117
|
||||||
|
MakeEntry("sched_setparam", UnknownArguments()), // 118
|
||||||
|
MakeEntry("sched_setscheduler", UnknownArguments()), // 119
|
||||||
|
MakeEntry("sched_getscheduler", UnknownArguments()), // 120
|
||||||
|
MakeEntry("sched_getparam", UnknownArguments()), // 121
|
||||||
|
MakeEntry("sched_setaffinity", UnknownArguments()), // 122
|
||||||
|
MakeEntry("sched_getaffinity", UnknownArguments()), // 123
|
||||||
|
MakeEntry("sched_yield", UnknownArguments()), // 124
|
||||||
|
MakeEntry("sched_get_priority_max", UnknownArguments()), // 125
|
||||||
|
MakeEntry("sched_get_priority_min", UnknownArguments()), // 126
|
||||||
|
MakeEntry("sched_rr_get_interval", UnknownArguments()), // 127
|
||||||
|
MakeEntry("restart_syscall", UnknownArguments()), // 128
|
||||||
|
MakeEntry("kill", kInt, kSignal, kGen, kGen, kGen, kGen), // 129
|
||||||
|
MakeEntry("tkill", kInt, kSignal, kGen, kGen, kGen, kGen), // 130
|
||||||
|
MakeEntry("tgkill", kInt, kInt, kSignal, kGen, kGen, kGen), // 131
|
||||||
|
MakeEntry("sigaltstack", UnknownArguments()), // 132
|
||||||
|
MakeEntry("rt_sigsuspend", UnknownArguments()), // 133
|
||||||
|
MakeEntry("rt_sigaction", kSignal, kHex, kHex, kInt, kGen, kGen), // 134
|
||||||
|
MakeEntry("rt_sigprocmask", UnknownArguments()), // 135
|
||||||
|
MakeEntry("rt_sigpending", UnknownArguments()), // 136
|
||||||
|
MakeEntry("rt_sigtimedwait", UnknownArguments()), // 137
|
||||||
|
MakeEntry("rt_sigqueueinfo", UnknownArguments()), // 138
|
||||||
|
MakeEntry("rt_sigreturn", UnknownArguments()), // 139
|
||||||
|
MakeEntry("setpriority", UnknownArguments()), // 140
|
||||||
|
MakeEntry("getpriority", UnknownArguments()), // 141
|
||||||
|
MakeEntry("reboot", UnknownArguments()), // 142
|
||||||
|
MakeEntry("setregid", UnknownArguments()), // 143
|
||||||
|
MakeEntry("setgid", UnknownArguments()), // 144
|
||||||
|
MakeEntry("setreuid", UnknownArguments()), // 145
|
||||||
|
MakeEntry("setuid", UnknownArguments()), // 146
|
||||||
|
MakeEntry("setresuid", UnknownArguments()), // 147
|
||||||
|
MakeEntry("getresuid", UnknownArguments()), // 148
|
||||||
|
MakeEntry("setresgid", UnknownArguments()), // 149
|
||||||
|
MakeEntry("getresgid", UnknownArguments()), // 150
|
||||||
|
MakeEntry("setfsuid", UnknownArguments()), // 151
|
||||||
|
MakeEntry("setfsgid", UnknownArguments()), // 152
|
||||||
|
MakeEntry("times", UnknownArguments()), // 153
|
||||||
|
MakeEntry("setpgid", UnknownArguments()), // 154
|
||||||
|
MakeEntry("getpgid", UnknownArguments()), // 155
|
||||||
|
MakeEntry("getsid", UnknownArguments()), // 156
|
||||||
|
MakeEntry("setsid", UnknownArguments()), // 157
|
||||||
|
MakeEntry("getgroups", UnknownArguments()), // 158
|
||||||
|
MakeEntry("setgroups", UnknownArguments()), // 159
|
||||||
|
MakeEntry("uname", UnknownArguments()), // 160
|
||||||
|
MakeEntry("sethostname", UnknownArguments()), // 161
|
||||||
|
MakeEntry("setdomainname", UnknownArguments()), // 162
|
||||||
|
MakeEntry("getrlimit", UnknownArguments()), // 163
|
||||||
|
MakeEntry("setrlimit", UnknownArguments()), // 164
|
||||||
|
MakeEntry("getrusage", UnknownArguments()), // 165
|
||||||
|
MakeEntry("umask", kHex, kGen, kGen, kGen, kGen, kGen), // 166
|
||||||
|
MakeEntry("prctl", kInt, kHex, kHex, kHex, kHex, kGen), // 167
|
||||||
|
MakeEntry("getcpu", kHex, kHex, kHex, kGen, kGen, kGen), // 168
|
||||||
|
MakeEntry("gettimeofday", kHex, kHex, kGen, kGen, kGen, kGen), // 169
|
||||||
|
MakeEntry("settimeofday", kHex, kHex, kGen, kGen, kGen, kGen), // 170
|
||||||
|
MakeEntry("adjtimex", UnknownArguments()), // 171
|
||||||
|
MakeEntry("getpid", UnknownArguments()), // 172
|
||||||
|
MakeEntry("getppid", UnknownArguments()), // 173
|
||||||
|
MakeEntry("getuid", UnknownArguments()), // 174
|
||||||
|
MakeEntry("geteuid", UnknownArguments()), // 175
|
||||||
|
MakeEntry("getgid", UnknownArguments()), // 176
|
||||||
|
MakeEntry("getegid", UnknownArguments()), // 177
|
||||||
|
MakeEntry("gettid", UnknownArguments()), // 178
|
||||||
|
MakeEntry("sysinfo", UnknownArguments()), // 179
|
||||||
|
MakeEntry("mq_open", UnknownArguments()), // 180
|
||||||
|
MakeEntry("mq_unlink", UnknownArguments()), // 181
|
||||||
|
MakeEntry("mq_timedsend", UnknownArguments()), // 182
|
||||||
|
MakeEntry("mq_timedreceive", UnknownArguments()), // 183
|
||||||
|
MakeEntry("mq_notify", UnknownArguments()), // 184
|
||||||
|
MakeEntry("mq_getsetattr", UnknownArguments()), // 185
|
||||||
|
MakeEntry("msgget", UnknownArguments()), // 186
|
||||||
|
MakeEntry("msgctl", UnknownArguments()), // 187
|
||||||
|
MakeEntry("msgrcv", UnknownArguments()), // 188
|
||||||
|
MakeEntry("msgsnd", UnknownArguments()), // 189
|
||||||
|
MakeEntry("semget", UnknownArguments()), // 190
|
||||||
|
MakeEntry("semctl", UnknownArguments()), // 191
|
||||||
|
MakeEntry("semtimedop", UnknownArguments()), // 192
|
||||||
|
MakeEntry("semop", UnknownArguments()), // 193
|
||||||
|
MakeEntry("shmget", UnknownArguments()), // 194
|
||||||
|
MakeEntry("shmctl", UnknownArguments()), // 195
|
||||||
|
MakeEntry("shmat", UnknownArguments()), // 196
|
||||||
|
MakeEntry("shmdt", UnknownArguments()), // 197
|
||||||
|
MakeEntry("socket", kAddressFamily, kInt, kInt, kGen, kGen, kGen), // 198
|
||||||
|
MakeEntry("socketpair", UnknownArguments()), // 199
|
||||||
|
MakeEntry("bind", UnknownArguments()), // 200
|
||||||
|
MakeEntry("listen", UnknownArguments()), // 201
|
||||||
|
MakeEntry("accept", UnknownArguments()), // 202
|
||||||
|
MakeEntry("connect", kInt, kSockaddr, kInt, kGen, kGen, kGen), // 203
|
||||||
|
MakeEntry("getsockname", UnknownArguments()), // 204
|
||||||
|
MakeEntry("getpeername", UnknownArguments()), // 205
|
||||||
|
MakeEntry("sendto", kInt, kGen, kInt, kHex, kSockaddr, kInt), // 206
|
||||||
|
MakeEntry("recvfrom", UnknownArguments()), // 207
|
||||||
|
MakeEntry("setsockopt", UnknownArguments()), // 208
|
||||||
|
MakeEntry("getsockopt", UnknownArguments()), // 209
|
||||||
|
MakeEntry("shutdown", UnknownArguments()), // 210
|
||||||
|
MakeEntry("sendmsg", kInt, kSockmsghdr, kHex, kGen, kGen, kGen), // 211
|
||||||
|
MakeEntry("recvmsg", UnknownArguments()), // 212
|
||||||
|
MakeEntry("readahead", UnknownArguments()), // 213
|
||||||
|
MakeEntry("brk", kHex, kGen, kGen, kGen, kGen, kGen), // 214
|
||||||
|
MakeEntry("munmap", kHex, kHex, kGen, kGen, kGen, kGen), // 215
|
||||||
|
MakeEntry("mremap", UnknownArguments()), // 216
|
||||||
|
MakeEntry("add_key", UnknownArguments()), // 217
|
||||||
|
MakeEntry("request_key", UnknownArguments()), // 218
|
||||||
|
MakeEntry("keyctl", UnknownArguments()), // 219
|
||||||
|
MakeEntry("clone", kCloneFlag, kHex, kHex, kHex, kHex, kGen), // 220
|
||||||
|
MakeEntry("execve", kPath, kHex, kHex, kGen, kGen, kGen), // 221
|
||||||
|
MakeEntry("mmap", kHex, kInt, kHex, kHex, kInt, kInt), // 222
|
||||||
|
MakeEntry("fadvise64", UnknownArguments()), // 223
|
||||||
|
MakeEntry("swapon", kPath, kHex, kGen, kGen, kGen, kGen), // 224
|
||||||
|
MakeEntry("swapoff", kPath, kGen, kGen, kGen, kGen, kGen), // 225
|
||||||
|
MakeEntry("mprotect", kHex, kHex, kHex, kGen, kGen, kGen), // 226
|
||||||
|
MakeEntry("msync", UnknownArguments()), // 227
|
||||||
|
MakeEntry("mlock", UnknownArguments()), // 228
|
||||||
|
MakeEntry("munlock", UnknownArguments()), // 229
|
||||||
|
MakeEntry("mlockall", UnknownArguments()), // 230
|
||||||
|
MakeEntry("munlockall", UnknownArguments()), // 231
|
||||||
|
MakeEntry("mincore", UnknownArguments()), // 232
|
||||||
|
MakeEntry("madvise", UnknownArguments()), // 233
|
||||||
|
MakeEntry("remap_file_pages", UnknownArguments()), // 234
|
||||||
|
MakeEntry("mbind", UnknownArguments()), // 235
|
||||||
|
MakeEntry("get_mempolicy", UnknownArguments()), // 236
|
||||||
|
MakeEntry("set_mempolicy", UnknownArguments()), // 237
|
||||||
|
MakeEntry("migrate_pages", UnknownArguments()), // 238
|
||||||
|
MakeEntry("move_pages", UnknownArguments()), // 239
|
||||||
|
MakeEntry("rt_tgsigqueueinfo", UnknownArguments()), // 240
|
||||||
|
MakeEntry("perf_event_open", UnknownArguments()), // 241
|
||||||
|
MakeEntry("accept4", UnknownArguments()), // 242
|
||||||
|
MakeEntry("recvmmsg", kInt, kHex, kHex, kHex, kGen, kGen), // 243
|
||||||
|
SYSCALLS_UNUSED("UNUSED244"), // 244
|
||||||
|
SYSCALLS_UNUSED("UNUSED245"), // 245
|
||||||
|
SYSCALLS_UNUSED("UNUSED246"), // 246
|
||||||
|
SYSCALLS_UNUSED("UNUSED247"), // 247
|
||||||
|
SYSCALLS_UNUSED("UNUSED248"), // 248
|
||||||
|
SYSCALLS_UNUSED("UNUSED249"), // 249
|
||||||
|
SYSCALLS_UNUSED("UNUSED250"), // 250
|
||||||
|
SYSCALLS_UNUSED("UNUSED251"), // 251
|
||||||
|
SYSCALLS_UNUSED("UNUSED252"), // 252
|
||||||
|
SYSCALLS_UNUSED("UNUSED253"), // 253
|
||||||
|
SYSCALLS_UNUSED("UNUSED254"), // 254
|
||||||
|
SYSCALLS_UNUSED("UNUSED255"), // 255
|
||||||
|
SYSCALLS_UNUSED("UNUSED256"), // 256
|
||||||
|
SYSCALLS_UNUSED("UNUSED257"), // 257
|
||||||
|
SYSCALLS_UNUSED("UNUSED258"), // 258
|
||||||
|
SYSCALLS_UNUSED("UNUSED259"), // 259
|
||||||
|
MakeEntry("wait4", kInt, kHex, kHex, kHex, kGen, kGen), // 260
|
||||||
|
MakeEntry("prlimit64", kInt, kInt, kHex, kHex, kGen, kGen), // 261
|
||||||
|
MakeEntry("fanotify_init", kHex, kHex, kInt, kGen, kGen, kGen), // 262
|
||||||
|
MakeEntry("fanotify_mark", kInt, kHex, kInt, kPath, kGen, kGen), // 263
|
||||||
|
MakeEntry("name_to_handle_at", kInt, kGen, kHex, kHex, kHex, kGen), // 264
|
||||||
|
MakeEntry("open_by_handle_at", kInt, kHex, kHex, kGen, kGen, kGen), // 265
|
||||||
|
MakeEntry("clock_adjtime", kInt, kHex, kGen, kGen, kGen, kGen), // 266
|
||||||
|
MakeEntry("syncfs", kInt, kGen, kGen, kGen, kGen, kGen), // 267
|
||||||
|
MakeEntry("setns", kInt, kHex, kGen, kGen, kGen, kGen), // 268
|
||||||
|
MakeEntry("sendmmsg", kInt, kHex, kInt, kHex, kGen, kGen), // 269
|
||||||
|
MakeEntry("process_vm_readv", kInt, kHex, kInt, kHex, kInt, kInt), // 270
|
||||||
|
MakeEntry("process_vm_writev", kInt, kHex, kInt, kHex, kInt, kInt), // 271
|
||||||
|
MakeEntry("kcmp", kInt, kInt, kInt, kHex, kHex, kGen), // 272
|
||||||
|
MakeEntry("finit_module", kInt, kPath, kHex, kGen, kGen, kGen), // 273
|
||||||
|
MakeEntry("sched_setattr", UnknownArguments()), // 274
|
||||||
|
MakeEntry("sched_getattr", UnknownArguments()), // 275
|
||||||
|
MakeEntry("renameat2", kGen, kPath, kGen, kPath, kGen, kGen), // 276
|
||||||
|
MakeEntry("seccomp", UnknownArguments()), // 277
|
||||||
|
MakeEntry("getrandom", UnknownArguments()), // 278
|
||||||
|
MakeEntry("memfd_create", UnknownArguments()), // 279
|
||||||
|
};
|
||||||
|
|
||||||
#undef SYSCALLS_UNUSED00_99
|
#undef SYSCALLS_UNUSED00_99
|
||||||
#undef SYSCALLS_UNUSED50_99
|
#undef SYSCALLS_UNUSED50_99
|
||||||
|
@ -1226,17 +1507,16 @@ constexpr SyscallTable::Entry kSyscallDataPPC64[] = {
|
||||||
#undef SYSCALLS_UNUSED0_9
|
#undef SYSCALLS_UNUSED0_9
|
||||||
#undef SYSCALLS_UNUSED
|
#undef SYSCALLS_UNUSED
|
||||||
|
|
||||||
SyscallTable SyscallTable::get(Syscall::CpuArch arch) {
|
SyscallTable SyscallTable::get(cpu::Architecture arch) {
|
||||||
switch (arch) {
|
switch (host_cpu::Architecture()) {
|
||||||
#if defined(__x86_64__)
|
case cpu::kX8664:
|
||||||
case Syscall::kX86_64:
|
|
||||||
return SyscallTable(kSyscallDataX8664);
|
return SyscallTable(kSyscallDataX8664);
|
||||||
case Syscall::kX86_32:
|
case cpu::kX86:
|
||||||
return SyscallTable(kSyscallDataX8632);
|
return SyscallTable(kSyscallDataX8632);
|
||||||
#elif defined(__powerpc64__)
|
case cpu::kPPC64LE:
|
||||||
case Syscall::kPPC_64:
|
return SyscallTable(kSyscallDataPPC64LE);
|
||||||
return SyscallTable(kSyscallDataPPC64);
|
case cpu::kArm64:
|
||||||
#endif
|
return SyscallTable(kSyscallDataArm64);
|
||||||
default:
|
default:
|
||||||
return SyscallTable();
|
return SyscallTable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/types/span.h"
|
#include "absl/types/span.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/syscall.h"
|
#include "sandboxed_api/sandbox2/syscall.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
@ -23,7 +24,7 @@ class SyscallTable {
|
||||||
struct Entry;
|
struct Entry;
|
||||||
|
|
||||||
// Returns the syscall table for the architecture.
|
// Returns the syscall table for the architecture.
|
||||||
static SyscallTable get(Syscall::CpuArch arch);
|
static SyscallTable get(cpu::Architecture arch);
|
||||||
|
|
||||||
int size() { return data_.size(); }
|
int size() { return data_.size(); }
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
|
|
||||||
using ::testing::Eq;
|
using ::testing::Eq;
|
||||||
using ::testing::StartsWith;
|
using ::testing::StartsWith;
|
||||||
|
@ -45,7 +46,7 @@ TEST(SyscallTest, Basic) {
|
||||||
EXPECT_THAT(arg_desc[2], Eq("0x5 [5]"));
|
EXPECT_THAT(arg_desc[2], Eq("0x5 [5]"));
|
||||||
EXPECT_THAT(
|
EXPECT_THAT(
|
||||||
syscall.GetDescription(),
|
syscall.GetDescription(),
|
||||||
Eq(absl::StrCat(Syscall::GetArchDescription(Syscall::GetHostArch()),
|
Eq(absl::StrCat(Syscall::GetArchDescription(host_cpu::Architecture()),
|
||||||
" read [", __NR_read,
|
" read [", __NR_read,
|
||||||
"](0x1 [1], 0xbadbeef, 0x5 [5]) IP: 0, STACK: 0")));
|
"](0x1 [1], 0xbadbeef, 0x5 [5]) IP: 0, STACK: 0")));
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ TEST(SyscallTest, Basic) {
|
||||||
TEST(SyscallTest, Empty) {
|
TEST(SyscallTest, Empty) {
|
||||||
Syscall syscall;
|
Syscall syscall;
|
||||||
|
|
||||||
EXPECT_THAT(syscall.arch(), Eq(Syscall::kUnknown));
|
EXPECT_THAT(syscall.arch(), Eq(cpu::kUnknown));
|
||||||
EXPECT_THAT(syscall.GetName(), StartsWith("UNKNOWN"));
|
EXPECT_THAT(syscall.GetName(), StartsWith("UNKNOWN"));
|
||||||
EXPECT_THAT(syscall.GetArgumentsDescription().size(), Eq(Syscall::kMaxArgs));
|
EXPECT_THAT(syscall.GetArgumentsDescription().size(), Eq(Syscall::kMaxArgs));
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,12 @@ STATIC_LINKOPTS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
# TODO(https://github.com/bazelbuild/bazel/issues/8672): Remove this workaround
|
# TODO(https://github.com/bazelbuild/bazel/issues/8672): Remove this workaround
|
||||||
EXTRA_FULLY_STATIC_LINKOPTS = ["-l:libstdc++.a"]
|
# Change is scheduled for Bazel 4.0. Specifying
|
||||||
|
# `--incompatible_linkopts_to_linklibs` also works
|
||||||
|
EXTRA_FULLY_STATIC_LINKOPTS = [
|
||||||
|
"-l:libstdc++.a",
|
||||||
|
"-l:libm.a",
|
||||||
|
]
|
||||||
|
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "abort",
|
name = "abort",
|
||||||
|
@ -173,6 +178,7 @@ cc_binary(
|
||||||
"fully_static_link", # link libc statically
|
"fully_static_link", # link libc statically
|
||||||
],
|
],
|
||||||
linkstatic = 1, # prefer static libraries
|
linkstatic = 1, # prefer static libraries
|
||||||
|
deps = ["//sandboxed_api/sandbox2:config"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# security: disable=cc-static-no-pie
|
# security: disable=cc-static-no-pie
|
||||||
|
|
|
@ -159,6 +159,7 @@ set_target_properties(policy PROPERTIES
|
||||||
)
|
)
|
||||||
target_link_libraries(policy PRIVATE
|
target_link_libraries(policy PRIVATE
|
||||||
sapi::base
|
sapi::base
|
||||||
|
sandbox2::config
|
||||||
${_sandbox2_fully_static_linkopts}
|
${_sandbox2_fully_static_linkopts}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
|
|
||||||
|
#ifdef SAPI_X86_64
|
||||||
void TestAMD64SyscallMismatch() {
|
void TestAMD64SyscallMismatch() {
|
||||||
int64_t result;
|
int64_t result;
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ void TestAMD64SyscallMismatchFs() {
|
||||||
: "rax", "rbx", "rcx");
|
: "rax", "rbx", "rcx");
|
||||||
exit(-result);
|
exit(-result);
|
||||||
}
|
}
|
||||||
#endif // defined(__x86_64__)
|
#endif
|
||||||
|
|
||||||
void TestPtrace() {
|
void TestPtrace() {
|
||||||
ptrace(PTRACE_SEIZE, getppid(), 0, 0);
|
ptrace(PTRACE_SEIZE, getppid(), 0, 0);
|
||||||
|
@ -97,14 +99,14 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
int testno = atoi(argv[1]); // NOLINT
|
int testno = atoi(argv[1]); // NOLINT
|
||||||
switch (testno) {
|
switch (testno) {
|
||||||
#if defined(__x86_64__)
|
#ifdef SAPI_X86_64
|
||||||
case 1:
|
case 1:
|
||||||
TestAMD64SyscallMismatch();
|
TestAMD64SyscallMismatch();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
TestAMD64SyscallMismatchFs();
|
TestAMD64SyscallMismatchFs();
|
||||||
break;
|
break;
|
||||||
#endif // defined(__x86_64__)
|
#endif
|
||||||
case 3:
|
case 3:
|
||||||
TestPtrace();
|
TestPtrace();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -39,13 +39,13 @@
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/strings/strip.h"
|
#include "absl/strings/strip.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
#include "sandboxed_api/util/raw_logging.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2::util {
|
||||||
namespace util {
|
|
||||||
|
|
||||||
void CharPtrArrToVecString(char* const* arr, std::vector<std::string>* vec) {
|
void CharPtrArrToVecString(char* const* arr, std::vector<std::string>* vec) {
|
||||||
for (int i = 0; arr[i]; ++i) {
|
for (int i = 0; arr[i]; ++i) {
|
||||||
|
@ -126,13 +126,11 @@ ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS
|
||||||
ABSL_ATTRIBUTE_NOINLINE
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
pid_t CloneAndJump(int flags, jmp_buf* env_ptr) {
|
pid_t CloneAndJump(int flags, jmp_buf* env_ptr) {
|
||||||
uint8_t stack_buf[PTHREAD_STACK_MIN] ABSL_CACHELINE_ALIGNED;
|
uint8_t stack_buf[PTHREAD_STACK_MIN] ABSL_CACHELINE_ALIGNED;
|
||||||
#if defined(__x86_64__) || defined(__x86__) || defined(__i386__) || \
|
static_assert(
|
||||||
defined(__powerpc64__)
|
host_cpu::IsX8664() || host_cpu::IsPPC64LE() || host_cpu::IsArm64(),
|
||||||
|
"Host CPU architecture not supported, see config.h");
|
||||||
// Stack grows down.
|
// Stack grows down.
|
||||||
void* stack = stack_buf + sizeof(stack_buf);
|
void* stack = stack_buf + sizeof(stack_buf);
|
||||||
#else
|
|
||||||
#error "Architecture is not supported"
|
|
||||||
#endif
|
|
||||||
int r;
|
int r;
|
||||||
{
|
{
|
||||||
r = clone(&ChildFunc, stack, flags, env_ptr, nullptr, nullptr, nullptr);
|
r = clone(&ChildFunc, stack, flags, env_ptr, nullptr, nullptr, nullptr);
|
||||||
|
@ -182,9 +180,9 @@ bool CreateMemFd(int* fd, const char* name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<int> Communicate(const std::vector<std::string>& argv,
|
absl::StatusOr<int> Communicate(const std::vector<std::string>& argv,
|
||||||
const std::vector<std::string>& envv,
|
const std::vector<std::string>& envv,
|
||||||
std::string* output) {
|
std::string* output) {
|
||||||
int cout_pipe[2];
|
int cout_pipe[2];
|
||||||
posix_spawn_file_actions_t action;
|
posix_spawn_file_actions_t action;
|
||||||
|
|
||||||
|
@ -280,7 +278,7 @@ std::string GetRlimitName(int resource) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr) {
|
absl::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr) {
|
||||||
std::string path(PATH_MAX, '\0');
|
std::string path(PATH_MAX, '\0');
|
||||||
iovec local_iov[] = {{&path[0], path.size()}};
|
iovec local_iov[] = {{&path[0], path.size()}};
|
||||||
|
|
||||||
|
@ -321,5 +319,4 @@ sapi::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace sandbox2::util
|
||||||
} // namespace sandbox2
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/base/macros.h"
|
#include "absl/base/macros.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
@ -62,9 +62,9 @@ bool CreateMemFd(int* fd, const char* name = "buffer_file");
|
||||||
|
|
||||||
// Executes a the program given by argv and the specified environment and
|
// Executes a the program given by argv and the specified environment and
|
||||||
// captures any output to stdout/stderr.
|
// captures any output to stdout/stderr.
|
||||||
sapi::StatusOr<int> Communicate(const std::vector<std::string>& argv,
|
absl::StatusOr<int> Communicate(const std::vector<std::string>& argv,
|
||||||
const std::vector<std::string>& envv,
|
const std::vector<std::string>& envv,
|
||||||
std::string* output);
|
std::string* output);
|
||||||
|
|
||||||
// Returns signal description.
|
// Returns signal description.
|
||||||
std::string GetSignalName(int signo);
|
std::string GetSignalName(int signo);
|
||||||
|
@ -74,7 +74,7 @@ std::string GetRlimitName(int resource);
|
||||||
|
|
||||||
// Reads a path string (NUL-terminated, shorter than PATH_MAX) from another
|
// Reads a path string (NUL-terminated, shorter than PATH_MAX) from another
|
||||||
// process memory
|
// process memory
|
||||||
sapi::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr);
|
absl::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr);
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace sandbox2
|
} // namespace sandbox2
|
||||||
|
|
|
@ -139,9 +139,9 @@ cc_library(
|
||||||
"//sandboxed_api/sandbox2:util",
|
"//sandboxed_api/sandbox2:util",
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/base:endian",
|
"@com_google_absl//absl/base:endian",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -173,8 +173,8 @@ cc_library(
|
||||||
deps = [
|
deps = [
|
||||||
":fileops",
|
":fileops",
|
||||||
":strerror",
|
":strerror",
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -199,8 +199,8 @@ cc_library(
|
||||||
hdrs = ["maps_parser.h"],
|
hdrs = ["maps_parser.h"],
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
"//sandboxed_api/util:statusor",
|
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -80,7 +80,6 @@ target_link_libraries(sandbox2_util_minielf PRIVATE
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::raw_logging
|
sapi::raw_logging
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2/util:temp_file
|
# sandboxed_api/sandbox2/util:temp_file
|
||||||
|
@ -95,7 +94,7 @@ target_link_libraries(sandbox2_util_temp_file
|
||||||
sandbox2::strerror
|
sandbox2::strerror
|
||||||
sapi::base
|
sapi::base
|
||||||
PUBLIC absl::status
|
PUBLIC absl::status
|
||||||
sapi::statusor
|
absl::statusor
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2/util:maps_parser
|
# sandboxed_api/sandbox2/util:maps_parser
|
||||||
|
@ -106,9 +105,9 @@ add_library(sandbox2_util_maps_parser STATIC
|
||||||
add_library(sandbox2::maps_parser ALIAS sandbox2_util_maps_parser)
|
add_library(sandbox2::maps_parser ALIAS sandbox2_util_maps_parser)
|
||||||
target_link_libraries(sandbox2_util_maps_parser PRIVATE
|
target_link_libraries(sandbox2_util_maps_parser PRIVATE
|
||||||
absl::status
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::strings
|
absl::strings
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2/util:runfiles
|
# sandboxed_api/sandbox2/util:runfiles
|
||||||
|
|
|
@ -15,11 +15,12 @@
|
||||||
#include "sandboxed_api/sandbox2/util/maps_parser.h"
|
#include "sandboxed_api/sandbox2/util/maps_parser.h"
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/str_split.h"
|
#include "absl/strings/str_split.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
sapi::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
|
absl::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
|
||||||
const std::string& contents) {
|
const std::string& contents) {
|
||||||
// Note: The format string
|
// Note: The format string
|
||||||
// https://github.com/torvalds/linux/blob/v4.14/fs/proc/task_mmu.c#L289
|
// https://github.com/torvalds/linux/blob/v4.14/fs/proc/task_mmu.c#L289
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "sandboxed_api/util/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ struct MapsEntry {
|
||||||
std::string path;
|
std::string path;
|
||||||
};
|
};
|
||||||
|
|
||||||
sapi::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
|
absl::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
|
||||||
const std::string& contents);
|
const std::string& contents);
|
||||||
|
|
||||||
} // namespace sandbox2
|
} // namespace sandbox2
|
||||||
|
|
|
@ -95,7 +95,7 @@ class ElfParser {
|
||||||
static constexpr size_t kMaxInterpreterSize = 1000;
|
static constexpr size_t kMaxInterpreterSize = 1000;
|
||||||
|
|
||||||
ElfParser() = default;
|
ElfParser() = default;
|
||||||
sapi::StatusOr<ElfFile> Parse(FILE* elf, uint32_t features);
|
absl::StatusOr<ElfFile> Parse(FILE* elf, uint32_t features);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Endianess support functions
|
// Endianess support functions
|
||||||
|
@ -133,16 +133,16 @@ class ElfParser {
|
||||||
// Reads elf header.
|
// Reads elf header.
|
||||||
absl::Status ReadFileHeader();
|
absl::Status ReadFileHeader();
|
||||||
// Reads a single elf program header.
|
// Reads a single elf program header.
|
||||||
sapi::StatusOr<Elf64_Phdr> ReadProgramHeader(absl::string_view src);
|
absl::StatusOr<Elf64_Phdr> ReadProgramHeader(absl::string_view src);
|
||||||
// Reads all elf program headers.
|
// Reads all elf program headers.
|
||||||
absl::Status ReadProgramHeaders();
|
absl::Status ReadProgramHeaders();
|
||||||
// Reads a single elf section header.
|
// Reads a single elf section header.
|
||||||
sapi::StatusOr<Elf64_Shdr> ReadSectionHeader(absl::string_view src);
|
absl::StatusOr<Elf64_Shdr> ReadSectionHeader(absl::string_view src);
|
||||||
// Reads all elf section headers.
|
// Reads all elf section headers.
|
||||||
absl::Status ReadSectionHeaders();
|
absl::Status ReadSectionHeaders();
|
||||||
// Reads contents of an elf section.
|
// Reads contents of an elf section.
|
||||||
sapi::StatusOr<std::string> ReadSectionContents(int idx);
|
absl::StatusOr<std::string> ReadSectionContents(int idx);
|
||||||
sapi::StatusOr<std::string> ReadSectionContents(
|
absl::StatusOr<std::string> ReadSectionContents(
|
||||||
const Elf64_Shdr& section_header);
|
const Elf64_Shdr& section_header);
|
||||||
// Reads all symbols from symtab section.
|
// Reads all symbols from symtab section.
|
||||||
absl::Status ReadSymbolsFromSymtab(const Elf64_Shdr& symtab);
|
absl::Status ReadSymbolsFromSymtab(const Elf64_Shdr& symtab);
|
||||||
|
@ -219,8 +219,7 @@ absl::Status ElfParser::ReadFileHeader() {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<Elf64_Shdr> ElfParser::ReadSectionHeader(
|
absl::StatusOr<Elf64_Shdr> ElfParser::ReadSectionHeader(absl::string_view src) {
|
||||||
absl::string_view src) {
|
|
||||||
if (src.size() < sizeof(Elf64_Shdr)) {
|
if (src.size() < sizeof(Elf64_Shdr)) {
|
||||||
return absl::FailedPreconditionError(
|
return absl::FailedPreconditionError(
|
||||||
absl::StrCat("invalid section header data: got ", src.size(),
|
absl::StrCat("invalid section header data: got ", src.size(),
|
||||||
|
@ -267,7 +266,7 @@ absl::Status ElfParser::ReadSectionHeaders() {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> ElfParser::ReadSectionContents(int idx) {
|
absl::StatusOr<std::string> ElfParser::ReadSectionContents(int idx) {
|
||||||
if (idx < 0 || idx >= section_headers_.size()) {
|
if (idx < 0 || idx >= section_headers_.size()) {
|
||||||
return absl::FailedPreconditionError(
|
return absl::FailedPreconditionError(
|
||||||
absl::StrCat("invalid section header index: ", idx));
|
absl::StrCat("invalid section header index: ", idx));
|
||||||
|
@ -275,7 +274,7 @@ sapi::StatusOr<std::string> ElfParser::ReadSectionContents(int idx) {
|
||||||
return ReadSectionContents(section_headers_.at(idx));
|
return ReadSectionContents(section_headers_.at(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> ElfParser::ReadSectionContents(
|
absl::StatusOr<std::string> ElfParser::ReadSectionContents(
|
||||||
const Elf64_Shdr& section_header) {
|
const Elf64_Shdr& section_header) {
|
||||||
auto offset = section_header.sh_offset;
|
auto offset = section_header.sh_offset;
|
||||||
if (offset > file_size_) {
|
if (offset > file_size_) {
|
||||||
|
@ -293,8 +292,7 @@ sapi::StatusOr<std::string> ElfParser::ReadSectionContents(
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<Elf64_Phdr> ElfParser::ReadProgramHeader(
|
absl::StatusOr<Elf64_Phdr> ElfParser::ReadProgramHeader(absl::string_view src) {
|
||||||
absl::string_view src) {
|
|
||||||
if (src.size() < sizeof(Elf64_Phdr)) {
|
if (src.size() < sizeof(Elf64_Phdr)) {
|
||||||
return absl::FailedPreconditionError(
|
return absl::FailedPreconditionError(
|
||||||
absl::StrCat("invalid program header data: got ", src.size(),
|
absl::StrCat("invalid program header data: got ", src.size(),
|
||||||
|
@ -456,7 +454,7 @@ absl::Status ElfParser::ReadImportedLibrariesFromDynamic(
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<ElfFile> ElfParser::Parse(FILE* elf, uint32_t features) {
|
absl::StatusOr<ElfFile> ElfParser::Parse(FILE* elf, uint32_t features) {
|
||||||
elf_ = elf;
|
elf_ = elf;
|
||||||
// Basic sanity check.
|
// Basic sanity check.
|
||||||
if (features & ~(ElfFile::kAll)) {
|
if (features & ~(ElfFile::kAll)) {
|
||||||
|
@ -513,8 +511,8 @@ sapi::StatusOr<ElfFile> ElfParser::Parse(FILE* elf, uint32_t features) {
|
||||||
return std::move(result_);
|
return std::move(result_);
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<ElfFile> ElfFile::ParseFromFile(const std::string& filename,
|
absl::StatusOr<ElfFile> ElfFile::ParseFromFile(const std::string& filename,
|
||||||
uint32_t features) {
|
uint32_t features) {
|
||||||
std::unique_ptr<FILE, void (*)(FILE*)> elf{fopen(filename.c_str(), "r"),
|
std::unique_ptr<FILE, void (*)(FILE*)> elf{fopen(filename.c_str(), "r"),
|
||||||
[](FILE* f) { fclose(f); }};
|
[](FILE* f) { fclose(f); }};
|
||||||
if (!elf) {
|
if (!elf) {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "sandboxed_api/util/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ class ElfFile {
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static sapi::StatusOr<ElfFile> ParseFromFile(const std::string& filename,
|
static absl::StatusOr<ElfFile> ParseFromFile(const std::string& filename,
|
||||||
uint32_t features);
|
uint32_t features);
|
||||||
|
|
||||||
int64_t file_size() const { return file_size_; }
|
int64_t file_size() const { return file_size_; }
|
||||||
const std::string& interpreter() const { return interpreter_; }
|
const std::string& interpreter() const { return interpreter_; }
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
|
@ -32,7 +33,7 @@ namespace {
|
||||||
constexpr absl::string_view kMktempSuffix = "XXXXXX";
|
constexpr absl::string_view kMktempSuffix = "XXXXXX";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
absl::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
||||||
absl::string_view prefix) {
|
absl::string_view prefix) {
|
||||||
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
||||||
int fd = mkstemp(&name_template[0]);
|
int fd = mkstemp(&name_template[0]);
|
||||||
|
@ -42,7 +43,7 @@ sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
||||||
return std::pair<std::string, int>{std::move(name_template), fd};
|
return std::pair<std::string, int>{std::move(name_template), fd};
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
absl::StatusOr<std::string> CreateNamedTempFileAndClose(
|
||||||
absl::string_view prefix) {
|
absl::string_view prefix) {
|
||||||
auto result_or = CreateNamedTempFile(prefix);
|
auto result_or = CreateNamedTempFile(prefix);
|
||||||
if (result_or.ok()) {
|
if (result_or.ok()) {
|
||||||
|
@ -55,7 +56,7 @@ sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
||||||
return result_or.status();
|
return result_or.status();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix) {
|
absl::StatusOr<std::string> CreateTempDir(absl::string_view prefix) {
|
||||||
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
||||||
if (mkdtemp(&name_template[0]) == nullptr) {
|
if (mkdtemp(&name_template[0]) == nullptr) {
|
||||||
return absl::UnknownError(absl::StrCat("mkdtemp():", StrError(errno)));
|
return absl::UnknownError(absl::StrCat("mkdtemp():", StrError(errno)));
|
||||||
|
|
|
@ -17,24 +17,24 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "sandboxed_api/util/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
// Creates a temporary file under a path starting with prefix. File is not
|
// Creates a temporary file under a path starting with prefix. File is not
|
||||||
// unlinked and its path is returned together with an open fd.
|
// unlinked and its path is returned together with an open fd.
|
||||||
sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
absl::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
||||||
absl::string_view prefix);
|
absl::string_view prefix);
|
||||||
|
|
||||||
// Creates a temporary file under a path starting with prefix. File is not
|
// Creates a temporary file under a path starting with prefix. File is not
|
||||||
// unlinked and its path is returned. FD of the created file is closed just
|
// unlinked and its path is returned. FD of the created file is closed just
|
||||||
// after creation.
|
// after creation.
|
||||||
sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
absl::StatusOr<std::string> CreateNamedTempFileAndClose(
|
||||||
absl::string_view prefix);
|
absl::string_view prefix);
|
||||||
|
|
||||||
// Creates a temporary directory under a path starting with prefix.
|
// Creates a temporary directory under a path starting with prefix.
|
||||||
// Returns the path of the created directory.
|
// Returns the path of the created directory.
|
||||||
sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix);
|
absl::StatusOr<std::string> CreateTempDir(absl::string_view prefix);
|
||||||
|
|
||||||
} // namespace sandbox2
|
} // namespace sandbox2
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
#include "sandboxed_api/sandbox2/testing.h"
|
#include "sandboxed_api/sandbox2/testing.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
|
|
||||||
using testing::Gt;
|
using ::testing::Gt;
|
||||||
using testing::IsTrue;
|
using ::testing::IsTrue;
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
|
@ -25,7 +25,6 @@ enum PBViolationType {
|
||||||
SYSCALL_ARCHITECTURE_MISMATCH = 3;
|
SYSCALL_ARCHITECTURE_MISMATCH = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// X86_64 not allowed (naming convention...)
|
|
||||||
message RegisterX8664 {
|
message RegisterX8664 {
|
||||||
uint64 r15 = 1;
|
uint64 r15 = 1;
|
||||||
uint64 r14 = 2;
|
uint64 r14 = 2;
|
||||||
|
@ -77,7 +76,6 @@ message RegisterPowerpc64 {
|
||||||
uint64 zero3 = 17;
|
uint64 zero3 = 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated.
|
|
||||||
message RegisterAarch64 {
|
message RegisterAarch64 {
|
||||||
repeated uint64 regs = 1;
|
repeated uint64 regs = 1;
|
||||||
uint64 sp = 2;
|
uint64 sp = 2;
|
||||||
|
@ -90,7 +88,7 @@ message RegisterValues {
|
||||||
oneof register_values {
|
oneof register_values {
|
||||||
RegisterX8664 register_x86_64 = 2;
|
RegisterX8664 register_x86_64 = 2;
|
||||||
RegisterPowerpc64 register_powerpc64 = 3;
|
RegisterPowerpc64 register_powerpc64 = 3;
|
||||||
RegisterAarch64 register_aarch64 = 4; // Deprecated.
|
RegisterAarch64 register_aarch64 = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,10 +103,10 @@ message SyscallDescription {
|
||||||
}
|
}
|
||||||
|
|
||||||
message FsDescription {
|
message FsDescription {
|
||||||
repeated string file_whitelist = 1;
|
repeated string file_allowlist = 1;
|
||||||
repeated string symlink_whitelist = 2;
|
repeated string symlink_allowlist = 2;
|
||||||
repeated string file_greylist = 3;
|
repeated string file_greylist = 3;
|
||||||
repeated string file_blacklist = 4;
|
repeated string file_denylist = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PolicyBuilderDescription {
|
message PolicyBuilderDescription {
|
||||||
|
@ -125,7 +123,7 @@ message NamespaceDescription {
|
||||||
message PolicyDescription {
|
message PolicyDescription {
|
||||||
bytes user_bpf_policy = 1;
|
bytes user_bpf_policy = 1;
|
||||||
reserved 2 to 5;
|
reserved 2 to 5;
|
||||||
// This requires additional fields. (e.g. whitelisted syscall #s)
|
// This requires additional fields. (e.g. allowed syscall numbers)
|
||||||
PolicyBuilderDescription policy_builder_description = 6;
|
PolicyBuilderDescription policy_builder_description = 6;
|
||||||
|
|
||||||
// namespace
|
// namespace
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "sandboxed_api/tools/clang_generator/emitter.h"
|
#include "sandboxed_api/tools/clang_generator/emitter.h"
|
||||||
|
|
||||||
#include "absl/random/random.h"
|
#include "absl/random/random.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/ascii.h"
|
#include "absl/strings/ascii.h"
|
||||||
#include "absl/strings/escaping.h"
|
#include "absl/strings/escaping.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
|
@ -46,10 +47,10 @@ constexpr absl::string_view kHeaderProlog =
|
||||||
|
|
||||||
#include "absl/base/macros.h"
|
#include "absl/base/macros.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "sandboxed_api/sandbox.h"
|
#include "sandboxed_api/sandbox.h"
|
||||||
#include "sandboxed_api/vars.h"
|
#include "sandboxed_api/vars.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
)";
|
)";
|
||||||
constexpr absl::string_view kHeaderEpilog =
|
constexpr absl::string_view kHeaderEpilog =
|
||||||
|
@ -196,7 +197,7 @@ std::string PrintFunctionPrototype(const clang::FunctionDecl* decl) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> EmitFunction(const clang::FunctionDecl* decl) {
|
absl::StatusOr<std::string> EmitFunction(const clang::FunctionDecl* decl) {
|
||||||
std::string out;
|
std::string out;
|
||||||
absl::StrAppend(&out, "\n// ", PrintFunctionPrototype(decl), "\n");
|
absl::StrAppend(&out, "\n// ", PrintFunctionPrototype(decl), "\n");
|
||||||
const std::string function_name = decl->getNameAsString();
|
const std::string function_name = decl->getNameAsString();
|
||||||
|
@ -248,7 +249,7 @@ sapi::StatusOr<std::string> EmitFunction(const clang::FunctionDecl* decl) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> EmitHeader(
|
absl::StatusOr<std::string> EmitHeader(
|
||||||
std::vector<clang::FunctionDecl*> functions, const QualTypeSet& types,
|
std::vector<clang::FunctionDecl*> functions, const QualTypeSet& types,
|
||||||
const GeneratorOptions& options) {
|
const GeneratorOptions& options) {
|
||||||
std::string out;
|
std::string out;
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
#include "sandboxed_api/tools/clang_generator/generator.h"
|
#include "sandboxed_api/tools/clang_generator/generator.h"
|
||||||
#include "sandboxed_api/tools/clang_generator/types.h"
|
#include "sandboxed_api/tools/clang_generator/types.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ namespace sapi {
|
||||||
std::string GetIncludeGuard(absl::string_view filename);
|
std::string GetIncludeGuard(absl::string_view filename);
|
||||||
|
|
||||||
// Outputs a formatted header for a list of functions and their related types.
|
// Outputs a formatted header for a list of functions and their related types.
|
||||||
sapi::StatusOr<std::string> EmitHeader(
|
absl::StatusOr<std::string> EmitHeader(
|
||||||
std::vector<clang::FunctionDecl*> functions, const QualTypeSet& types,
|
std::vector<clang::FunctionDecl*> functions, const QualTypeSet& types,
|
||||||
const GeneratorOptions& options);
|
const GeneratorOptions& options);
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "clang/Format/Format.h"
|
#include "clang/Format/Format.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/tools/clang_generator/diagnostics.h"
|
#include "sandboxed_api/tools/clang_generator/diagnostics.h"
|
||||||
#include "sandboxed_api/tools/clang_generator/emitter.h"
|
#include "sandboxed_api/tools/clang_generator/emitter.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -67,8 +67,8 @@ bool GeneratorASTVisitor::VisitFunctionDecl(clang::FunctionDecl* decl) {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
sapi::StatusOr<std::string> ReformatGoogleStyle(const std::string& filename,
|
absl::StatusOr<std::string> ReformatGoogleStyle(const std::string& filename,
|
||||||
const std::string& code) {
|
const std::string& code) {
|
||||||
// Configure code style based on Google style, but enforce pointer alignment
|
// Configure code style based on Google style, but enforce pointer alignment
|
||||||
clang::format::FormatStyle style =
|
clang::format::FormatStyle style =
|
||||||
clang::format::getGoogleStyle(clang::format::FormatStyle::LK_Cpp);
|
clang::format::getGoogleStyle(clang::format::FormatStyle::LK_Cpp);
|
||||||
|
|
|
@ -20,13 +20,13 @@
|
||||||
#include "absl/container/flat_hash_set.h"
|
#include "absl/container/flat_hash_set.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "clang/AST/ASTConsumer.h"
|
#include "clang/AST/ASTConsumer.h"
|
||||||
#include "clang/AST/RecursiveASTVisitor.h"
|
#include "clang/AST/RecursiveASTVisitor.h"
|
||||||
#include "clang/Frontend/CompilerInstance.h"
|
#include "clang/Frontend/CompilerInstance.h"
|
||||||
#include "clang/Frontend/FrontendAction.h"
|
#include "clang/Frontend/FrontendAction.h"
|
||||||
#include "clang/Tooling/Tooling.h"
|
#include "clang/Tooling/Tooling.h"
|
||||||
#include "sandboxed_api/tools/clang_generator/types.h"
|
#include "sandboxed_api/tools/clang_generator/types.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ class GeneratorASTVisitor
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
sapi::StatusOr<std::string> ReformatGoogleStyle(const std::string& filename,
|
absl::StatusOr<std::string> ReformatGoogleStyle(const std::string& filename,
|
||||||
const std::string& code);
|
const std::string& code);
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ std::string MapQualTypeReturn(const clang::ASTContext& context,
|
||||||
return "absl::Status";
|
return "absl::Status";
|
||||||
}
|
}
|
||||||
// Remove const qualifier like in MapQualType().
|
// Remove const qualifier like in MapQualType().
|
||||||
return absl::StrCat("::sapi::StatusOr<",
|
return absl::StrCat("absl::StatusOr<",
|
||||||
MaybeRemoveConst(context, qual).getAsString(), ">");
|
MaybeRemoveConst(context, qual).getAsString(), ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ std::string MapQualTypeParameter(const clang::ASTContext& context,
|
||||||
|
|
||||||
// Maps a qualified type used as a function return type to a type name
|
// Maps a qualified type used as a function return type to a type name
|
||||||
// compatible with the generated Sandboxed API. Uses MapQualTypeParameter() and
|
// compatible with the generated Sandboxed API. Uses MapQualTypeParameter() and
|
||||||
// wraps the type in a sapi::StatusOr<> if qual is non-void. Otherwise returns
|
// wraps the type in an absl::StatusOr<> if qual is non-void. Otherwise returns
|
||||||
// absl::Status.
|
// absl::Status.
|
||||||
std::string MapQualTypeReturn(const clang::ASTContext& context,
|
std::string MapQualTypeReturn(const clang::ASTContext& context,
|
||||||
clang::QualType qual);
|
clang::QualType qual);
|
||||||
|
|
|
@ -461,7 +461,7 @@ class ReturnType(ArgumentType):
|
||||||
"""Class representing function return type.
|
"""Class representing function return type.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
return_type: sapi::StatusOr<T> where T is original return type, or
|
return_type: absl::StatusOr<T> where T is original return type, or
|
||||||
absl::Status for functions returning void
|
absl::Status for functions returning void
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ class ReturnType(ArgumentType):
|
||||||
"""Returns function return type prepared from the type."""
|
"""Returns function return type prepared from the type."""
|
||||||
# TODO(szwl): const ptrs do not play well with SAPI C++ API...
|
# TODO(szwl): const ptrs do not play well with SAPI C++ API...
|
||||||
spelling = self._clang_type.spelling.replace('const', '')
|
spelling = self._clang_type.spelling.replace('const', '')
|
||||||
return_type = 'sapi::StatusOr<{}>'.format(spelling)
|
return_type = 'absl::StatusOr<{}>'.format(spelling)
|
||||||
return_type = 'absl::Status' if self.is_void() else return_type
|
return_type = 'absl::Status' if self.is_void() else return_type
|
||||||
return return_type
|
return return_type
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class TestApi {
|
||||||
::sapi::Sandbox* sandbox() const { return sandbox_; }
|
::sapi::Sandbox* sandbox() const { return sandbox_; }
|
||||||
|
|
||||||
// int function_a(int, int)
|
// int function_a(int, int)
|
||||||
sapi::StatusOr<int> function_a(int x, int y) {
|
absl::StatusOr<int> function_a(int x, int y) {
|
||||||
::sapi::v::Int ret;
|
::sapi::v::Int ret;
|
||||||
::sapi::v::Int x_((x));
|
::sapi::v::Int x_((x));
|
||||||
::sapi::v::Int y_((y));
|
::sapi::v::Int y_((y));
|
||||||
|
@ -42,7 +42,7 @@ class TestApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// int types_1(bool, unsigned char, char, unsigned short, short)
|
// int types_1(bool, unsigned char, char, unsigned short, short)
|
||||||
sapi::StatusOr<int> types_1(bool a0, unsigned char a1, char a2, unsigned short a3, short a4) {
|
absl::StatusOr<int> types_1(bool a0, unsigned char a1, char a2, unsigned short a3, short a4) {
|
||||||
::sapi::v::Int ret;
|
::sapi::v::Int ret;
|
||||||
::sapi::v::Bool a0_((a0));
|
::sapi::v::Bool a0_((a0));
|
||||||
::sapi::v::UChar a1_((a1));
|
::sapi::v::UChar a1_((a1));
|
||||||
|
@ -55,7 +55,7 @@ class TestApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// int types_2(int, unsigned int, long, unsigned long)
|
// int types_2(int, unsigned int, long, unsigned long)
|
||||||
sapi::StatusOr<int> types_2(int a0, unsigned int a1, long a2, unsigned long a3) {
|
absl::StatusOr<int> types_2(int a0, unsigned int a1, long a2, unsigned long a3) {
|
||||||
::sapi::v::Int ret;
|
::sapi::v::Int ret;
|
||||||
::sapi::v::Int a0_((a0));
|
::sapi::v::Int a0_((a0));
|
||||||
::sapi::v::UInt a1_((a1));
|
::sapi::v::UInt a1_((a1));
|
||||||
|
@ -67,7 +67,7 @@ class TestApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// int types_3(long long, unsigned long long, float, double)
|
// int types_3(long long, unsigned long long, float, double)
|
||||||
sapi::StatusOr<int> types_3(long long a0, unsigned long long a1, float a2, double a3) {
|
absl::StatusOr<int> types_3(long long a0, unsigned long long a1, float a2, double a3) {
|
||||||
::sapi::v::Int ret;
|
::sapi::v::Int ret;
|
||||||
::sapi::v::LLong a0_((a0));
|
::sapi::v::LLong a0_((a0));
|
||||||
::sapi::v::ULLong a1_((a1));
|
::sapi::v::ULLong a1_((a1));
|
||||||
|
@ -79,7 +79,7 @@ class TestApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// int types_4(signed char, short, int, long)
|
// int types_4(signed char, short, int, long)
|
||||||
sapi::StatusOr<int> types_4(signed char a0, short a1, int a2, long a3) {
|
absl::StatusOr<int> types_4(signed char a0, short a1, int a2, long a3) {
|
||||||
::sapi::v::Int ret;
|
::sapi::v::Int ret;
|
||||||
::sapi::v::SChar a0_((a0));
|
::sapi::v::SChar a0_((a0));
|
||||||
::sapi::v::Short a1_((a1));
|
::sapi::v::Short a1_((a1));
|
||||||
|
@ -91,7 +91,7 @@ class TestApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// int types_5(long long, long double)
|
// int types_5(long long, long double)
|
||||||
sapi::StatusOr<int> types_5(long long a0, long double a1) {
|
absl::StatusOr<int> types_5(long long a0, long double a1) {
|
||||||
::sapi::v::Int ret;
|
::sapi::v::Int ret;
|
||||||
::sapi::v::LLong a0_((a0));
|
::sapi::v::LLong a0_((a0));
|
||||||
::sapi::v::Reg<long double> a1_((a1));
|
::sapi::v::Reg<long double> a1_((a1));
|
||||||
|
@ -136,7 +136,7 @@ class TestApi {
|
||||||
::sapi::Sandbox* sandbox() const { return sandbox_; }
|
::sapi::Sandbox* sandbox() const { return sandbox_; }
|
||||||
|
|
||||||
// uint function(uintp)
|
// uint function(uintp)
|
||||||
sapi::StatusOr<uint> function(::sapi::v::Ptr* a) {
|
absl::StatusOr<uint> function(::sapi::v::Ptr* a) {
|
||||||
::sapi::v::UInt ret;
|
::sapi::v::UInt ret;
|
||||||
|
|
||||||
SAPI_RETURN_IF_ERROR(sandbox_->Call("function", &ret, a));
|
SAPI_RETURN_IF_ERROR(sandbox_->Call("function", &ret, a));
|
||||||
|
@ -173,7 +173,7 @@ class TestApi {
|
||||||
::sapi::Sandbox* sandbox() const { return sandbox_; }
|
::sapi::Sandbox* sandbox() const { return sandbox_; }
|
||||||
|
|
||||||
// ProcessStatus ProcessDatapoint(ProcessStatus)
|
// ProcessStatus ProcessDatapoint(ProcessStatus)
|
||||||
sapi::StatusOr<ProcessStatus> ProcessDatapoint(ProcessStatus status) {
|
absl::StatusOr<ProcessStatus> ProcessDatapoint(ProcessStatus status) {
|
||||||
::sapi::v::IntBase<ProcessStatus> ret;
|
::sapi::v::IntBase<ProcessStatus> ret;
|
||||||
::sapi::v::IntBase<ProcessStatus> status_((status));
|
::sapi::v::IntBase<ProcessStatus> status_((status));
|
||||||
|
|
||||||
|
|
|
@ -45,20 +45,15 @@ cc_library(
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "statusor",
|
name = "statusor",
|
||||||
hdrs = ["statusor.h"],
|
hdrs = ["statusor.h"],
|
||||||
copts = sapi_platform_copts(),
|
deprecation = "Migrate to `absl::StatusOr<T>`",
|
||||||
visibility = ["//visibility:public"],
|
|
||||||
deps = [
|
deps = [
|
||||||
":raw_logging",
|
|
||||||
":status",
|
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/base:log_severity",
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/status",
|
|
||||||
"@com_google_absl//absl/types:variant",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# gMock matchers for absl::Status and sapi::StatusOr<T> and a gUnit printer
|
# gMock matchers for absl::Status and absl::StatusOr<T> and a gUnit printer
|
||||||
# extension for sapi::StatusOr<T>.
|
# extension. Adapted from the version in Asylo.
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "status_matchers",
|
name = "status_matchers",
|
||||||
testonly = 1,
|
testonly = 1,
|
||||||
|
@ -67,8 +62,8 @@ cc_library(
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
":status",
|
":status",
|
||||||
":statusor",
|
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/types:optional",
|
"@com_google_absl//absl/types:optional",
|
||||||
"@com_google_googletest//:gtest",
|
"@com_google_googletest//:gtest",
|
||||||
],
|
],
|
||||||
|
@ -87,19 +82,6 @@ cc_test(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tests for the StatusOr template class.
|
|
||||||
cc_test(
|
|
||||||
name = "statusor_test",
|
|
||||||
srcs = ["statusor_test.cc"],
|
|
||||||
copts = sapi_platform_copts(),
|
|
||||||
deps = [
|
|
||||||
":status",
|
|
||||||
":status_matchers",
|
|
||||||
":statusor",
|
|
||||||
"@com_google_googletest//:gtest_main",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Tests for the Status macros.
|
# Tests for the Status macros.
|
||||||
cc_test(
|
cc_test(
|
||||||
name = "status_macros_test",
|
name = "status_macros_test",
|
||||||
|
@ -108,9 +90,9 @@ cc_test(
|
||||||
deps = [
|
deps = [
|
||||||
":status",
|
":status",
|
||||||
":status_matchers",
|
":status_matchers",
|
||||||
":statusor",
|
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_googletest//:gtest_main",
|
"@com_google_googletest//:gtest_main",
|
||||||
],
|
],
|
||||||
|
|
|
@ -48,11 +48,10 @@ add_library(sapi_util_statusor STATIC
|
||||||
)
|
)
|
||||||
add_library(sapi::statusor ALIAS sapi_util_statusor)
|
add_library(sapi::statusor ALIAS sapi_util_statusor)
|
||||||
target_link_libraries(sapi_util_statusor PRIVATE
|
target_link_libraries(sapi_util_statusor PRIVATE
|
||||||
absl::base
|
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::variant
|
absl::status
|
||||||
sapi::raw_logging
|
absl::statusor
|
||||||
sapi::status
|
sapi::base
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/util:flag
|
# sandboxed_api/util:flag
|
||||||
|
@ -90,7 +89,6 @@ if(SAPI_ENABLE_TESTS)
|
||||||
sapi::base
|
sapi::base
|
||||||
PUBLIC absl::status
|
PUBLIC absl::status
|
||||||
sapi::status
|
sapi::status
|
||||||
sapi::statusor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/util:status_test
|
# sandboxed_api/util:status_test
|
||||||
|
@ -98,20 +96,24 @@ if(SAPI_ENABLE_TESTS)
|
||||||
status_test.cc
|
status_test.cc
|
||||||
)
|
)
|
||||||
target_link_libraries(status_test PRIVATE
|
target_link_libraries(status_test PRIVATE
|
||||||
|
sapi::status
|
||||||
sapi::status_matchers
|
sapi::status_matchers
|
||||||
sapi::test_main
|
sapi::test_main
|
||||||
|
absl::status
|
||||||
absl::type_traits
|
absl::type_traits
|
||||||
)
|
)
|
||||||
gtest_discover_tests(status_test)
|
gtest_discover_tests(status_test)
|
||||||
|
|
||||||
# sandboxed_api/util:statusor_test
|
# sandboxed_api/util:status_macros_test
|
||||||
add_executable(statusor_test
|
add_executable(status_macros_test
|
||||||
statusor_test.cc
|
status_macros_test.cc
|
||||||
)
|
)
|
||||||
target_link_libraries(statusor_test PRIVATE
|
target_link_libraries(status_macros_test PRIVATE
|
||||||
sapi::status_matchers
|
sapi::status_matchers
|
||||||
sapi::test_main
|
sapi::test_main
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
absl::type_traits
|
absl::type_traits
|
||||||
)
|
)
|
||||||
gtest_discover_tests(statusor_test)
|
gtest_discover_tests(status_macros_test)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -12,10 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// This file and it's implementation provide a custom fork of
|
|
||||||
// util/task/status.h. This will become obsolete and will be replaced once
|
|
||||||
// Abseil releases absl::Status.
|
|
||||||
|
|
||||||
#ifndef THIRD_PARTY_SAPI_UTIL_STATUS_H_
|
#ifndef THIRD_PARTY_SAPI_UTIL_STATUS_H_
|
||||||
#define THIRD_PARTY_SAPI_UTIL_STATUS_H_
|
#define THIRD_PARTY_SAPI_UTIL_STATUS_H_
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,6 @@
|
||||||
if (ABSL_PREDICT_FALSE(!statusor.ok())) { \
|
if (ABSL_PREDICT_FALSE(!statusor.ok())) { \
|
||||||
return statusor.status(); \
|
return statusor.status(); \
|
||||||
} \
|
} \
|
||||||
lhs = std::move(statusor).ValueOrDie();
|
lhs = std::move(statusor).value();
|
||||||
|
|
||||||
#endif // THIRD_PARTY_SAPI_UTIL_STATUS_MACROS_H_
|
#endif // THIRD_PARTY_SAPI_UTIL_STATUS_MACROS_H_
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
#include "sandboxed_api/util/status.h"
|
||||||
#include "sandboxed_api/util/status_matchers.h"
|
#include "sandboxed_api/util/status_matchers.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -52,17 +52,17 @@ TEST(ReturnIfError, ReturnsOnErrorFromLambda) {
|
||||||
TEST(AssignOrReturn, AssignsMultipleVariablesInSequence) {
|
TEST(AssignOrReturn, AssignsMultipleVariablesInSequence) {
|
||||||
auto func = []() -> absl::Status {
|
auto func = []() -> absl::Status {
|
||||||
int value1;
|
int value1;
|
||||||
SAPI_ASSIGN_OR_RETURN(value1, StatusOr<int>(1));
|
SAPI_ASSIGN_OR_RETURN(value1, absl::StatusOr<int>(1));
|
||||||
EXPECT_EQ(1, value1);
|
EXPECT_EQ(1, value1);
|
||||||
int value2;
|
int value2;
|
||||||
SAPI_ASSIGN_OR_RETURN(value2, StatusOr<int>(2));
|
SAPI_ASSIGN_OR_RETURN(value2, absl::StatusOr<int>(2));
|
||||||
EXPECT_EQ(2, value2);
|
EXPECT_EQ(2, value2);
|
||||||
int value3;
|
int value3;
|
||||||
SAPI_ASSIGN_OR_RETURN(value3, StatusOr<int>(3));
|
SAPI_ASSIGN_OR_RETURN(value3, absl::StatusOr<int>(3));
|
||||||
EXPECT_EQ(3, value3);
|
EXPECT_EQ(3, value3);
|
||||||
int value4;
|
int value4;
|
||||||
SAPI_ASSIGN_OR_RETURN(value4,
|
SAPI_ASSIGN_OR_RETURN(value4,
|
||||||
StatusOr<int>(absl::UnknownError("EXPECTED")));
|
absl::StatusOr<int>(absl::UnknownError("EXPECTED")));
|
||||||
return absl::UnknownError(absl::StrCat("ERROR: assigned value ", value4));
|
return absl::UnknownError(absl::StrCat("ERROR: assigned value ", value4));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,11 +72,12 @@ TEST(AssignOrReturn, AssignsMultipleVariablesInSequence) {
|
||||||
TEST(AssignOrReturn, AssignsRepeatedlyToSingleVariable) {
|
TEST(AssignOrReturn, AssignsRepeatedlyToSingleVariable) {
|
||||||
auto func = []() -> absl::Status {
|
auto func = []() -> absl::Status {
|
||||||
int value = 1;
|
int value = 1;
|
||||||
SAPI_ASSIGN_OR_RETURN(value, StatusOr<int>(2));
|
SAPI_ASSIGN_OR_RETURN(value, absl::StatusOr<int>(2));
|
||||||
EXPECT_EQ(2, value);
|
EXPECT_EQ(2, value);
|
||||||
SAPI_ASSIGN_OR_RETURN(value, StatusOr<int>(3));
|
SAPI_ASSIGN_OR_RETURN(value, absl::StatusOr<int>(3));
|
||||||
EXPECT_EQ(3, value);
|
EXPECT_EQ(3, value);
|
||||||
SAPI_ASSIGN_OR_RETURN(value, StatusOr<int>(absl::UnknownError("EXPECTED")));
|
SAPI_ASSIGN_OR_RETURN(value,
|
||||||
|
absl::StatusOr<int>(absl::UnknownError("EXPECTED")));
|
||||||
return absl::UnknownError("ERROR");
|
return absl::UnknownError("ERROR");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ TEST(AssignOrReturn, MovesUniquePtr) {
|
||||||
auto func = []() -> absl::Status {
|
auto func = []() -> absl::Status {
|
||||||
std::unique_ptr<int> ptr;
|
std::unique_ptr<int> ptr;
|
||||||
SAPI_ASSIGN_OR_RETURN(
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
ptr, StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(1)));
|
ptr, absl::StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(1)));
|
||||||
EXPECT_EQ(*ptr, 1);
|
EXPECT_EQ(*ptr, 1);
|
||||||
return absl::UnknownError("EXPECTED");
|
return absl::UnknownError("EXPECTED");
|
||||||
};
|
};
|
||||||
|
@ -98,8 +99,8 @@ TEST(AssignOrReturn, MovesUniquePtr) {
|
||||||
TEST(AssignOrReturn, DoesNotAssignUniquePtrOnErrorStatus) {
|
TEST(AssignOrReturn, DoesNotAssignUniquePtrOnErrorStatus) {
|
||||||
auto func = []() -> absl::Status {
|
auto func = []() -> absl::Status {
|
||||||
std::unique_ptr<int> ptr;
|
std::unique_ptr<int> ptr;
|
||||||
SAPI_ASSIGN_OR_RETURN(
|
SAPI_ASSIGN_OR_RETURN(ptr, absl::StatusOr<std::unique_ptr<int>>(
|
||||||
ptr, StatusOr<std::unique_ptr<int>>(absl::UnknownError("EXPECTED")));
|
absl::UnknownError("EXPECTED")));
|
||||||
EXPECT_EQ(ptr, nullptr);
|
EXPECT_EQ(ptr, nullptr);
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
};
|
};
|
||||||
|
@ -111,10 +112,10 @@ TEST(AssignOrReturn, MovesUniquePtrRepeatedlyToSingleVariable) {
|
||||||
auto func = []() -> absl::Status {
|
auto func = []() -> absl::Status {
|
||||||
std::unique_ptr<int> ptr;
|
std::unique_ptr<int> ptr;
|
||||||
SAPI_ASSIGN_OR_RETURN(
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
ptr, StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(1)));
|
ptr, absl::StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(1)));
|
||||||
EXPECT_EQ(*ptr, 1);
|
EXPECT_EQ(*ptr, 1);
|
||||||
SAPI_ASSIGN_OR_RETURN(
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
ptr, StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(2)));
|
ptr, absl::StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(2)));
|
||||||
EXPECT_EQ(*ptr, 2);
|
EXPECT_EQ(*ptr, 2);
|
||||||
return absl::UnknownError("EXPECTED");
|
return absl::UnknownError("EXPECTED");
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "sandboxed_api/util/status_macros.h"
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
#define SAPI_ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
|
#define SAPI_ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
|
||||||
SAPI_ASSERT_OK_AND_ASSIGN_IMPL( \
|
SAPI_ASSERT_OK_AND_ASSIGN_IMPL( \
|
||||||
|
|
|
@ -12,220 +12,17 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// This file and it's implementation provide a custom fork of
|
|
||||||
// util/task/statusor.h. This will become obsolete and will be replaced once
|
|
||||||
// Abseil releases absl::Status.
|
|
||||||
|
|
||||||
#ifndef THIRD_PARTY_SAPI_UTIL_STATUSOR_H_
|
#ifndef THIRD_PARTY_SAPI_UTIL_STATUSOR_H_
|
||||||
#define THIRD_PARTY_SAPI_UTIL_STATUSOR_H_
|
#define THIRD_PARTY_SAPI_UTIL_STATUSOR_H_
|
||||||
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "absl/base/internal/raw_logging.h"
|
|
||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
#include "absl/base/log_severity.h"
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/status/status.h"
|
|
||||||
#include "absl/types/variant.h"
|
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ABSL_MUST_USE_RESULT StatusOr {
|
using StatusOr ABSL_DEPRECATED("Use absl::StatusOr instead") =
|
||||||
template <typename U>
|
absl::StatusOr<T>;
|
||||||
friend class StatusOr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using element_type = T;
|
|
||||||
|
|
||||||
explicit StatusOr() : variant_(absl::UnknownError("")) {}
|
|
||||||
|
|
||||||
StatusOr(const StatusOr&) = default;
|
|
||||||
StatusOr& operator=(const StatusOr&) = default;
|
|
||||||
|
|
||||||
StatusOr(StatusOr&&) = default;
|
|
||||||
StatusOr& operator=(StatusOr&&) = default;
|
|
||||||
|
|
||||||
// Not implemented:
|
|
||||||
// template <typename U> StatusOr(const StatusOr<U>& other)
|
|
||||||
// template <typename U> StatusOr(StatusOr<U>&& other)
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
StatusOr& operator=(const StatusOr<U>& other) {
|
|
||||||
if (other.ok()) {
|
|
||||||
variant_ = other.value();
|
|
||||||
} else {
|
|
||||||
variant_ = other.status();
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
StatusOr& operator=(StatusOr<U>&& other) {
|
|
||||||
if (other.ok()) {
|
|
||||||
variant_ = std::move(other).value();
|
|
||||||
} else {
|
|
||||||
variant_ = std::move(other).status();
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusOr(const T& value) : variant_(value) {}
|
|
||||||
|
|
||||||
StatusOr(const absl::Status& status) : variant_(status) { EnsureNotOk(); }
|
|
||||||
|
|
||||||
// Not implemented:
|
|
||||||
// template <typename U = T> StatusOr& operator=(U&& value)
|
|
||||||
|
|
||||||
StatusOr(T&& value) : variant_(std::move(value)) {}
|
|
||||||
|
|
||||||
StatusOr(absl::Status&& value) : variant_(std::move(value)) {}
|
|
||||||
|
|
||||||
StatusOr& operator=(absl::Status&& status) {
|
|
||||||
variant_ = std::move(status);
|
|
||||||
EnsureNotOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
explicit StatusOr(absl::in_place_t, Args&&... args)
|
|
||||||
: StatusOr(T(std::forward<Args>(args)...)) {}
|
|
||||||
|
|
||||||
template <typename U, typename... Args>
|
|
||||||
explicit StatusOr(absl::in_place_t, std::initializer_list<U> ilist,
|
|
||||||
Args&&... args)
|
|
||||||
: StatusOr(ilist, U(std::forward<Args>(args)...)) {}
|
|
||||||
|
|
||||||
explicit operator bool() const { return ok(); }
|
|
||||||
|
|
||||||
ABSL_MUST_USE_RESULT bool ok() const {
|
|
||||||
return absl::holds_alternative<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const absl::Status& status() const& {
|
|
||||||
static const auto* ok_status = new absl::Status();
|
|
||||||
return ok() ? *ok_status : absl::get<absl::Status>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::Status status() && {
|
|
||||||
return ok() ? absl::OkStatus()
|
|
||||||
: std::move(absl::get<absl::Status>(variant_));
|
|
||||||
}
|
|
||||||
|
|
||||||
const T& value() const& {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
T& value() & {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const T&& value() const&& {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(std::move(variant_));
|
|
||||||
}
|
|
||||||
|
|
||||||
T&& value() && {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(std::move(variant_));
|
|
||||||
}
|
|
||||||
|
|
||||||
const T& ValueOrDie() const& {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
T& ValueOrDie() & {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
T&& ValueOrDie() && {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(std::move(variant_));
|
|
||||||
}
|
|
||||||
|
|
||||||
const T& operator*() const& {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator*() & {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const T&& operator*() const&& {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(std::move(variant_));
|
|
||||||
}
|
|
||||||
|
|
||||||
T&& operator*() && {
|
|
||||||
EnsureOk();
|
|
||||||
return absl::get<T>(std::move(variant_));
|
|
||||||
}
|
|
||||||
|
|
||||||
const T* operator->() const {
|
|
||||||
EnsureOk();
|
|
||||||
return &absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator->() {
|
|
||||||
EnsureOk();
|
|
||||||
return &absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
T value_or(U&& default_value) const& {
|
|
||||||
if (ok()) {
|
|
||||||
return absl::get<T>(variant_);
|
|
||||||
}
|
|
||||||
return std::forward<U>(default_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
T value_or(U&& default_value) && {
|
|
||||||
if (ok()) {
|
|
||||||
return absl::get<T>(std::move(variant_));
|
|
||||||
}
|
|
||||||
return std::forward<U>(default_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IgnoreError() const { /* no-op */
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
T& emplace(Args&&... args) {
|
|
||||||
return variant_.template emplace<T>(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U, typename... Args>
|
|
||||||
T& emplace(std::initializer_list<U> ilist, Args&&... args) {
|
|
||||||
return variant_.template emplace<T>(ilist, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void EnsureOk() const {
|
|
||||||
if (!ok()) {
|
|
||||||
// GoogleTest needs this exact error message for death tests to work.
|
|
||||||
SAPI_RAW_LOG(FATAL,
|
|
||||||
"Attempting to fetch value instead of handling error %s",
|
|
||||||
status().message());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnsureNotOk() const {
|
|
||||||
if (ok()) {
|
|
||||||
SAPI_RAW_LOG(
|
|
||||||
FATAL,
|
|
||||||
"An OK status is not a valid constructor argument to StatusOr<T>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::variant<absl::Status, T> variant_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sapi
|
} // namespace sapi
|
||||||
|
|
||||||
|
|
|
@ -1,407 +0,0 @@
|
||||||
// Copyright 2019 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// This file is a custom fork of the version in Asylo. This will become obsolete
|
|
||||||
// and will be replaced once Abseil releases absl::Status.
|
|
||||||
|
|
||||||
#include "sandboxed_api/util/statusor.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include "sandboxed_api/util/status_matchers.h"
|
|
||||||
|
|
||||||
using ::testing::Eq;
|
|
||||||
using ::testing::IsFalse;
|
|
||||||
using ::testing::Not;
|
|
||||||
using ::testing::Pointee;
|
|
||||||
|
|
||||||
namespace sapi {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr auto kErrorCode = absl::StatusCode::kInvalidArgument;
|
|
||||||
constexpr char kErrorMessage[] = "Invalid argument";
|
|
||||||
|
|
||||||
const int kIntElement = 47;
|
|
||||||
constexpr char kStringElement[] = "47 is 42, corrected for inflation";
|
|
||||||
|
|
||||||
// A data type without a default constructor.
|
|
||||||
struct Foo {
|
|
||||||
int bar;
|
|
||||||
std::string baz;
|
|
||||||
|
|
||||||
explicit Foo(int value) : bar(value), baz(kStringElement) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A data type with dynamically-allocated data.
|
|
||||||
struct HeapAllocatedObject {
|
|
||||||
int* value;
|
|
||||||
|
|
||||||
HeapAllocatedObject() {
|
|
||||||
value = new int;
|
|
||||||
*value = kIntElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapAllocatedObject(const HeapAllocatedObject& other) { *this = other; }
|
|
||||||
|
|
||||||
HeapAllocatedObject& operator=(const HeapAllocatedObject& other) {
|
|
||||||
value = new int;
|
|
||||||
*value = *other.value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapAllocatedObject(HeapAllocatedObject&& other) { *this = std::move(other); }
|
|
||||||
|
|
||||||
HeapAllocatedObject& operator=(HeapAllocatedObject&& other) {
|
|
||||||
value = other.value;
|
|
||||||
other.value = nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~HeapAllocatedObject() { delete value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructs a Foo.
|
|
||||||
struct FooCtor {
|
|
||||||
using value_type = Foo;
|
|
||||||
|
|
||||||
Foo operator()() { return Foo(kIntElement); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructs a HeapAllocatedObject.
|
|
||||||
struct HeapAllocatedObjectCtor {
|
|
||||||
using value_type = HeapAllocatedObject;
|
|
||||||
|
|
||||||
HeapAllocatedObject operator()() { return HeapAllocatedObject(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructs an integer.
|
|
||||||
struct IntCtor {
|
|
||||||
using value_type = int;
|
|
||||||
|
|
||||||
int operator()() { return kIntElement; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructs a string.
|
|
||||||
struct StringCtor {
|
|
||||||
using value_type = std::string;
|
|
||||||
|
|
||||||
std::string operator()() { return std::string(kStringElement); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructs a vector of strings.
|
|
||||||
struct StringVectorCtor {
|
|
||||||
using value_type = std::vector<std::string>;
|
|
||||||
|
|
||||||
std::vector<std::string> operator()() {
|
|
||||||
return {kStringElement, kErrorMessage};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const Foo& lhs, const Foo& rhs) {
|
|
||||||
return (lhs.bar == rhs.bar) && (lhs.baz == rhs.baz);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const HeapAllocatedObject& lhs,
|
|
||||||
const HeapAllocatedObject& rhs) {
|
|
||||||
return *lhs.value == *rhs.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns an rvalue reference to the StatusOr<T> object pointed to by
|
|
||||||
// |statusor|.
|
|
||||||
template <typename T>
|
|
||||||
StatusOr<T>&& MoveStatusOr(StatusOr<T>* statusor) {
|
|
||||||
return std::move(*statusor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// A test fixture is required for typed tests.
|
|
||||||
template <typename T>
|
|
||||||
class StatusOrTest : public ::testing::Test {};
|
|
||||||
|
|
||||||
using TestTypes = ::testing::Types<IntCtor, FooCtor, StringCtor,
|
|
||||||
StringVectorCtor, HeapAllocatedObjectCtor>;
|
|
||||||
TYPED_TEST_SUITE(StatusOrTest, TestTypes);
|
|
||||||
|
|
||||||
// Verify that the default constructor for StatusOr constructs an object with a
|
|
||||||
// non-ok status.
|
|
||||||
TYPED_TEST(StatusOrTest, ConstructorDefault) {
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor;
|
|
||||||
EXPECT_THAT(statusor.ok(), IsFalse());
|
|
||||||
EXPECT_THAT(statusor.status().code(), Eq(absl::StatusCode::kUnknown));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that StatusOr can be constructed from a Status object.
|
|
||||||
TYPED_TEST(StatusOrTest, ConstructorStatus) {
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor(
|
|
||||||
absl::Status(kErrorCode, kErrorMessage));
|
|
||||||
|
|
||||||
EXPECT_THAT(statusor.ok(), IsFalse());
|
|
||||||
EXPECT_THAT(statusor.status().ok(), IsFalse());
|
|
||||||
EXPECT_THAT(statusor.status(), Eq(absl::Status(kErrorCode, kErrorMessage)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that StatusOr can be constructed from an object of its element type.
|
|
||||||
TYPED_TEST(StatusOrTest, ConstructorElementConstReference) {
|
|
||||||
auto value = TypeParam()();
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor{value};
|
|
||||||
|
|
||||||
ASSERT_THAT(statusor, IsOk());
|
|
||||||
ASSERT_THAT(statusor.status(), IsOk());
|
|
||||||
EXPECT_THAT(statusor.ValueOrDie(), Eq(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that StatusOr can be constructed from an rvalue reference of an object
|
|
||||||
// of its element type.
|
|
||||||
TYPED_TEST(StatusOrTest, ConstructorElementRValue) {
|
|
||||||
auto value = TypeParam()();
|
|
||||||
auto value_copy(value);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor(std::move(value));
|
|
||||||
|
|
||||||
ASSERT_THAT(statusor, IsOk());
|
|
||||||
ASSERT_THAT(statusor.status(), IsOk());
|
|
||||||
|
|
||||||
// Compare to a copy of the original value, since the original was moved.
|
|
||||||
EXPECT_THAT(statusor.ValueOrDie(), Eq(value_copy));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that StatusOr can be copy-constructed from a StatusOr with a non-ok
|
|
||||||
// status.
|
|
||||||
TYPED_TEST(StatusOrTest, CopyConstructorNonOkStatus) {
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1 =
|
|
||||||
absl::Status(kErrorCode, kErrorMessage);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2(statusor1);
|
|
||||||
|
|
||||||
EXPECT_THAT(statusor1.ok(), Eq(statusor2.ok()));
|
|
||||||
EXPECT_THAT(statusor1.status(), Eq(statusor2.status()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that StatusOr can be copy-constructed from a StatusOr with an ok
|
|
||||||
// status.
|
|
||||||
TYPED_TEST(StatusOrTest, CopyConstructorOkStatus) {
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1{TypeParam()()};
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2{statusor1};
|
|
||||||
|
|
||||||
EXPECT_THAT(statusor1.ok(), Eq(statusor2.ok()));
|
|
||||||
ASSERT_THAT(statusor2, IsOk());
|
|
||||||
EXPECT_THAT(statusor1.ValueOrDie(), Eq(statusor2.ValueOrDie()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that copy-assignment of a StatusOr with a non-ok is working as
|
|
||||||
// expected.
|
|
||||||
TYPED_TEST(StatusOrTest, CopyAssignmentNonOkStatus) {
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1{
|
|
||||||
absl::Status(kErrorCode, kErrorMessage)};
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2{TypeParam()()};
|
|
||||||
|
|
||||||
// Invoke the copy-assignment operator.
|
|
||||||
statusor2 = statusor1;
|
|
||||||
EXPECT_THAT(statusor1.ok(), Eq(statusor2.ok()));
|
|
||||||
EXPECT_THAT(statusor1.status(), Eq(statusor2.status()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that copy-assignment of a StatusOr with an ok status is working as
|
|
||||||
// expected.
|
|
||||||
TYPED_TEST(StatusOrTest, CopyAssignmentOkStatus) {
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1{TypeParam()()};
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2{
|
|
||||||
absl::Status(kErrorCode, kErrorMessage)};
|
|
||||||
|
|
||||||
// Invoke the copy-assignment operator.
|
|
||||||
statusor2 = statusor1;
|
|
||||||
EXPECT_THAT(statusor1.ok(), Eq(statusor2.ok()));
|
|
||||||
ASSERT_THAT(statusor2, IsOk());
|
|
||||||
EXPECT_THAT(statusor1.ValueOrDie(), Eq(statusor2.ValueOrDie()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that StatusOr can be move-constructed from a StatusOr with a non-ok
|
|
||||||
// status.
|
|
||||||
TYPED_TEST(StatusOrTest, MoveConstructorNonOkStatus) {
|
|
||||||
absl::Status status(kErrorCode, kErrorMessage);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1(status);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2(std::move(statusor1));
|
|
||||||
|
|
||||||
// Verify that the status of the donor object was updated.
|
|
||||||
EXPECT_THAT(statusor1.ok(), IsFalse()); // NOLINT
|
|
||||||
EXPECT_THAT(statusor1.status(), StatusIs(absl::StatusCode::kInternal));
|
|
||||||
|
|
||||||
// Verify that the destination object contains the status previously held by
|
|
||||||
// the donor.
|
|
||||||
EXPECT_THAT(statusor2.ok(), IsFalse());
|
|
||||||
EXPECT_THAT(statusor2.status(), Eq(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that StatusOr can be move-constructed from a StatusOr with an ok
|
|
||||||
// status.
|
|
||||||
TYPED_TEST(StatusOrTest, MoveConstructorOkStatus) {
|
|
||||||
auto value = TypeParam()();
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1(value);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2(std::move(statusor1));
|
|
||||||
|
|
||||||
// The destination object should possess the value previously held by the
|
|
||||||
// donor.
|
|
||||||
ASSERT_THAT(statusor2, IsOk());
|
|
||||||
EXPECT_THAT(statusor2.ValueOrDie(), Eq(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that move-assignment from a StatusOr with a non-ok status is working
|
|
||||||
// as expected.
|
|
||||||
TYPED_TEST(StatusOrTest, MoveAssignmentOperatorNonOkStatus) {
|
|
||||||
absl::Status status(kErrorCode, kErrorMessage);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1(status);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2{TypeParam()()};
|
|
||||||
|
|
||||||
// Invoke the move-assignment operator.
|
|
||||||
statusor2 = std::move(statusor1);
|
|
||||||
|
|
||||||
// Verify that the status of the donor object was updated.
|
|
||||||
EXPECT_THAT(statusor1.ok(), IsFalse()); // NOLINT
|
|
||||||
EXPECT_THAT(statusor1.status(), StatusIs(absl::StatusCode::kInternal));
|
|
||||||
|
|
||||||
// Verify that the destination object contains the status previously held by
|
|
||||||
// the donor.
|
|
||||||
EXPECT_THAT(statusor2.ok(), IsFalse());
|
|
||||||
EXPECT_THAT(statusor2.status(), Eq(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that move-assignment from a StatusOr with an ok status is working as
|
|
||||||
// expected.
|
|
||||||
TYPED_TEST(StatusOrTest, MoveAssignmentOperatorOkStatus) {
|
|
||||||
auto value = TypeParam()();
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor1(value);
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor2(
|
|
||||||
absl::Status(kErrorCode, kErrorMessage));
|
|
||||||
|
|
||||||
// Invoke the move-assignment operator.
|
|
||||||
statusor2 = std::move(statusor1);
|
|
||||||
|
|
||||||
// The destination object should possess the value previously held by the
|
|
||||||
// donor.
|
|
||||||
ASSERT_THAT(statusor2, IsOk());
|
|
||||||
EXPECT_THAT(statusor2.ValueOrDie(), Eq(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that the sapi::IsOk() gMock matcher works with StatusOr<T>.
|
|
||||||
TYPED_TEST(StatusOrTest, IsOkMatcher) {
|
|
||||||
auto value = TypeParam()();
|
|
||||||
StatusOr<typename TypeParam::value_type> statusor(value);
|
|
||||||
|
|
||||||
EXPECT_THAT(statusor, IsOk());
|
|
||||||
|
|
||||||
statusor = StatusOr<typename TypeParam::value_type>(
|
|
||||||
absl::Status(kErrorCode, kErrorMessage));
|
|
||||||
EXPECT_THAT(statusor, Not(IsOk()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests for move-only types. These tests use std::unique_ptr<> as the
|
|
||||||
// test type, since it is valuable to support this type in the Asylo infra.
|
|
||||||
// These tests are not part of the typed test suite for the following reasons:
|
|
||||||
// * std::unique_ptr<> cannot be used as a type in tests that expect
|
|
||||||
// the test type to support copy operations.
|
|
||||||
// * std::unique_ptr<> provides an equality operator that checks equality of
|
|
||||||
// the underlying ptr. Consequently, it is difficult to generalize existing
|
|
||||||
// tests that verify ValueOrDie() functionality using equality comparisons.
|
|
||||||
|
|
||||||
// Verify that a StatusOr object can be constructed from a move-only type.
|
|
||||||
TEST(StatusOrTest, InitializationMoveOnlyType) {
|
|
||||||
auto* str = new std::string(kStringElement);
|
|
||||||
std::unique_ptr<std::string> value(str);
|
|
||||||
StatusOr<std::unique_ptr<std::string>> statusor(std::move(value));
|
|
||||||
|
|
||||||
ASSERT_THAT(statusor, IsOk());
|
|
||||||
EXPECT_THAT(statusor.ValueOrDie().get(), Eq(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that a StatusOr object can be move-constructed from a move-only type.
|
|
||||||
TEST(StatusOrTest, MoveConstructorMoveOnlyType) {
|
|
||||||
auto* str = new std::string(kStringElement);
|
|
||||||
std::unique_ptr<std::string> value(str);
|
|
||||||
StatusOr<std::unique_ptr<std::string>> statusor1(std::move(value));
|
|
||||||
StatusOr<std::unique_ptr<std::string>> statusor2(std::move(statusor1));
|
|
||||||
|
|
||||||
// The destination object should possess the value previously held by the
|
|
||||||
// donor.
|
|
||||||
ASSERT_THAT(statusor2, IsOk());
|
|
||||||
EXPECT_THAT(statusor2.ValueOrDie().get(), Eq(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that a StatusOr object can be move-assigned to from a StatusOr object
|
|
||||||
// containing a move-only type.
|
|
||||||
TEST(StatusOrTest, MoveAssignmentMoveOnlyType) {
|
|
||||||
auto* str = new std::string(kStringElement);
|
|
||||||
std::unique_ptr<std::string> value(str);
|
|
||||||
StatusOr<std::unique_ptr<std::string>> statusor1(std::move(value));
|
|
||||||
StatusOr<std::unique_ptr<std::string>> statusor2(
|
|
||||||
absl::Status(kErrorCode, kErrorMessage));
|
|
||||||
|
|
||||||
// Invoke the move-assignment operator.
|
|
||||||
statusor2 = std::move(statusor1);
|
|
||||||
|
|
||||||
// The destination object should possess the value previously held by the
|
|
||||||
// donor.
|
|
||||||
ASSERT_THAT(statusor2, IsOk());
|
|
||||||
EXPECT_THAT(statusor2.ValueOrDie().get(), Eq(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that a value can be moved out of a StatusOr object via ValueOrDie().
|
|
||||||
TEST(StatusOrTest, ValueOrDieMovedValue) {
|
|
||||||
auto* str = new std::string(kStringElement);
|
|
||||||
std::unique_ptr<std::string> value(str);
|
|
||||||
StatusOr<std::unique_ptr<std::string>> statusor(std::move(value));
|
|
||||||
|
|
||||||
std::unique_ptr<std::string> moved_value = std::move(statusor).ValueOrDie();
|
|
||||||
EXPECT_THAT(moved_value.get(), Eq(str));
|
|
||||||
EXPECT_THAT(*moved_value, Eq(kStringElement));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(StatusOrTest, MapToStatusOrUniquePtr) {
|
|
||||||
// A reduced version of a problematic type found in the wild. All of the
|
|
||||||
// operations below should compile.
|
|
||||||
using MapType = std::map<std::string, StatusOr<std::unique_ptr<int>>>;
|
|
||||||
|
|
||||||
MapType a;
|
|
||||||
|
|
||||||
// Move-construction
|
|
||||||
MapType b(std::move(a));
|
|
||||||
|
|
||||||
// Move-assignment
|
|
||||||
a = std::move(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(StatusOrTest, ValueOrOk) {
|
|
||||||
const StatusOr<int> status_or = 0;
|
|
||||||
EXPECT_EQ(status_or.value_or(-1), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(StatusOrTest, ValueOrDefault) {
|
|
||||||
const StatusOr<int> status_or = absl::CancelledError();
|
|
||||||
EXPECT_EQ(status_or.value_or(-1), -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(StatusOrTest, MoveOnlyValueOrOk) {
|
|
||||||
EXPECT_THAT(StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(0))
|
|
||||||
.value_or(absl::make_unique<int>(-1)),
|
|
||||||
Pointee(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(StatusOr, MoveOnlyValueOrDefault) {
|
|
||||||
EXPECT_THAT(StatusOr<std::unique_ptr<int>>(absl::CancelledError())
|
|
||||||
.value_or(absl::make_unique<int>(-1)),
|
|
||||||
Pointee(-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
} // namespace sapi
|
|
|
@ -41,7 +41,7 @@ class Proto : public Pointable, public Var {
|
||||||
explicit Proto(const T& proto)
|
explicit Proto(const T& proto)
|
||||||
: wrapped_var_(SerializeProto(proto).value()) {}
|
: wrapped_var_(SerializeProto(proto).value()) {}
|
||||||
|
|
||||||
static sapi::StatusOr<Proto<T>> FromMessage(const T& proto) {
|
static absl::StatusOr<Proto<T>> FromMessage(const T& proto) {
|
||||||
SAPI_ASSIGN_OR_RETURN(std::vector<uint8_t> len_val, SerializeProto(proto));
|
SAPI_ASSIGN_OR_RETURN(std::vector<uint8_t> len_val, SerializeProto(proto));
|
||||||
return Proto(len_val);
|
return Proto(len_val);
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ class Proto : public Pointable, public Var {
|
||||||
void* GetLocal() const override { return wrapped_var_.GetLocal(); }
|
void* GetLocal() const override { return wrapped_var_.GetLocal(); }
|
||||||
|
|
||||||
// Returns a copy of the stored protobuf object.
|
// Returns a copy of the stored protobuf object.
|
||||||
sapi::StatusOr<T> GetMessage() const {
|
absl::StatusOr<T> GetMessage() const {
|
||||||
return DeserializeProto<T>(
|
return DeserializeProto<T>(
|
||||||
reinterpret_cast<const char*>(wrapped_var_.GetData()),
|
reinterpret_cast<const char*>(wrapped_var_.GetData()),
|
||||||
wrapped_var_.GetDataSize());
|
wrapped_var_.GetDataSize());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user