mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Add external embedding example
This change contains a "hello world"-style example library to be sandboxed. It consists of a stand-alone CMake and Bazel project that uses Sandboxed API as its dependency. To use Sandboxed API in an external project, it should be enough to copy the files in the `sandboxed_api/examples/hello_sapi` directory as a starting point.
This commit is contained in:
parent
ba47adc21d
commit
2c8c9a489a
2
sandboxed_api/examples/hello_sapi/.bazelrc
Normal file
2
sandboxed_api/examples/hello_sapi/.bazelrc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Build in C++17 mode without a custom CROSSTOOL
|
||||||
|
build --cxxopt=-std=c++17
|
60
sandboxed_api/examples/hello_sapi/BUILD.bazel
Normal file
60
sandboxed_api/examples/hello_sapi/BUILD.bazel
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@com_google_sandboxed_api//sandboxed_api/bazel:sapi.bzl",
|
||||||
|
"sapi_library",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Library with code that should be sandboxed
|
||||||
|
cc_library(
|
||||||
|
name = "hello_lib",
|
||||||
|
srcs = ["hello_lib.cc"],
|
||||||
|
alwayslink = 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sandboxed API for the library above
|
||||||
|
sapi_library(
|
||||||
|
name = "hello_sapi",
|
||||||
|
functions = [
|
||||||
|
"AddTwoIntegers",
|
||||||
|
],
|
||||||
|
input_files = ["hello_lib.cc"],
|
||||||
|
lib = ":hello_lib",
|
||||||
|
lib_name = "Hello",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Main executable demonstrating how the sandboxed library is used
|
||||||
|
cc_binary(
|
||||||
|
name = "hello",
|
||||||
|
srcs = ["hello_main.cc"],
|
||||||
|
copts = ["-I."], # To find the generated header
|
||||||
|
deps = [":hello_sapi"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Another example using the same library, but using the Transaction API that
|
||||||
|
# automatically retries sandbox operations. Also demonstates error handling
|
||||||
|
# and a custom security policy.
|
||||||
|
cc_binary(
|
||||||
|
name = "hello_transacted",
|
||||||
|
srcs = ["hello_transacted.cc"],
|
||||||
|
copts = ["-I."], # To find the generated header
|
||||||
|
deps = [
|
||||||
|
":hello_sapi",
|
||||||
|
"@com_google_absl//absl/memory",
|
||||||
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_sandboxed_api//sandboxed_api/util:status",
|
||||||
|
],
|
||||||
|
)
|
82
sandboxed_api/examples/hello_sapi/CMakeLists.txt
Normal file
82
sandboxed_api/examples/hello_sapi/CMakeLists.txt
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# Example that demonstrates how to embed Sandboxed API into a project using
|
||||||
|
# CMake.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
|
project(hello_sapi_project CXX)
|
||||||
|
|
||||||
|
# Path to the Sandboxed API source tree. Unlike Bazel, CMake does not download
|
||||||
|
# downstream dependencies by default. So the option below needs to be adjusted
|
||||||
|
# to point to a local checkout or a Git submodule.
|
||||||
|
# The default value is chosen so that this example can be easily tried out for
|
||||||
|
# a regular checkout of Sandboxed API.
|
||||||
|
set(SAPI_ROOT "${PROJECT_SOURCE_DIR}/../../.."
|
||||||
|
CACHE PATH "Path to the Sandboxed API source tree")
|
||||||
|
|
||||||
|
# Configure options and include Sandboxed API as a sub-directory.
|
||||||
|
set(SAPI_ENABLE_EXAMPLES OFF CACHE BOOL "")
|
||||||
|
set(SAPI_ENABLE_TESTS OFF CACHE BOOL "")
|
||||||
|
add_subdirectory("${SAPI_ROOT}"
|
||||||
|
"${CMAKE_BINARY_DIR}/sandboxed-api-build" EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# Interface library with common settings for this projects
|
||||||
|
add_library(hello_base INTERFACE)
|
||||||
|
add_library(hello::base ALIAS hello_base)
|
||||||
|
target_compile_features(hello_base INTERFACE cxx_std_17)
|
||||||
|
target_include_directories(hello_base INTERFACE
|
||||||
|
"${PROJECT_BINARY_DIR}" # To find the generated SAPI header
|
||||||
|
)
|
||||||
|
|
||||||
|
# Library with code that should be sandboxed
|
||||||
|
add_library(hello_lib STATIC
|
||||||
|
hello_lib.cc
|
||||||
|
)
|
||||||
|
target_link_libraries(hello_lib PRIVATE
|
||||||
|
hello::base
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sandboxed API for the library above
|
||||||
|
add_sapi_library(hello_sapi
|
||||||
|
FUNCTIONS AddTwoIntegers
|
||||||
|
INPUTS hello_lib.cc
|
||||||
|
LIBRARY hello_lib
|
||||||
|
LIBRARY_NAME Hello
|
||||||
|
NAMESPACE ""
|
||||||
|
)
|
||||||
|
add_library(hello::sapi ALIAS hello_sapi)
|
||||||
|
|
||||||
|
# Main executable demonstrating how the sandboxed library is used
|
||||||
|
add_executable(hello
|
||||||
|
hello_main.cc
|
||||||
|
)
|
||||||
|
target_link_libraries(hello PRIVATE
|
||||||
|
hello::base
|
||||||
|
hello::sapi
|
||||||
|
sapi::sapi
|
||||||
|
)
|
||||||
|
|
||||||
|
# Another example using the same library, but using the Transaction API that
|
||||||
|
# automatically retries sandbox operations. Also demonstates error handling
|
||||||
|
# and a custom security policy.
|
||||||
|
add_executable(hello_transacted
|
||||||
|
hello_transacted.cc
|
||||||
|
)
|
||||||
|
target_link_libraries(hello_transacted PRIVATE
|
||||||
|
hello::base
|
||||||
|
hello::sapi
|
||||||
|
sapi::sapi
|
||||||
|
)
|
49
sandboxed_api/examples/hello_sapi/WORKSPACE.bazel
Normal file
49
sandboxed_api/examples/hello_sapi/WORKSPACE.bazel
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# Example workspace demonstrating how to embed Sandboxed API into a project
|
||||||
|
# using Bazel.
|
||||||
|
|
||||||
|
workspace(name = "com_google_sandboxed_api_hello")
|
||||||
|
|
||||||
|
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
|
||||||
|
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
||||||
|
|
||||||
|
# Include the Sandboxed API dependency if it does not already exist in this
|
||||||
|
# project. This ensures that this workspace plays well with other external
|
||||||
|
# dependencies that might use Sandboxed API.
|
||||||
|
maybe(
|
||||||
|
git_repository,
|
||||||
|
name = "com_google_sandboxed_api",
|
||||||
|
# This example depends on the latest master. In an embedding project, it
|
||||||
|
# is advisable to pin Sandboxed API to a specific version.
|
||||||
|
# commit = "ba47adc21d4c9bc316f3c7c32b0faaef952c111e", # 2020-05-15
|
||||||
|
remote = "https://github.com/google/sandboxed-api.git",
|
||||||
|
)
|
||||||
|
|
||||||
|
# From here on, Sandboxed API files are available. The statements below setup
|
||||||
|
# transitive dependencies such as Abseil. Like above, those will only be
|
||||||
|
# included if they don't already exist in the project.
|
||||||
|
load(
|
||||||
|
"@com_google_sandboxed_api//sandboxed_api/bazel:sapi_deps.bzl",
|
||||||
|
"sapi_deps",
|
||||||
|
)
|
||||||
|
|
||||||
|
sapi_deps()
|
||||||
|
|
||||||
|
# Need to separately setup Protobuf dependencies in order for the build rules
|
||||||
|
# to work.
|
||||||
|
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||||
|
|
||||||
|
protobuf_deps()
|
19
sandboxed_api/examples/hello_sapi/hello_lib.cc
Normal file
19
sandboxed_api/examples/hello_sapi/hello_lib.cc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// Adds two integer values and returns the result, serving as an example
|
||||||
|
// function that will be sandboxed.
|
||||||
|
extern "C" int AddTwoIntegers(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
38
sandboxed_api/examples/hello_sapi/hello_main.cc
Normal file
38
sandboxed_api/examples/hello_sapi/hello_main.cc
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// A minimal "hello world" style example of how to use Sandboxed API. This
|
||||||
|
// example does not include any error handling and will simply abort if
|
||||||
|
// something goes wrong.
|
||||||
|
// As the library function that is being called into is pure computation (i.e.
|
||||||
|
// does not issue any syscalls), the restricted default sandbox policy is being
|
||||||
|
// used.
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "hello_sapi.sapi.h" // Generated header
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Calling into a sandboxee to add two numbers...\n";
|
||||||
|
|
||||||
|
HelloSandbox sandbox;
|
||||||
|
sandbox.Init().IgnoreError();
|
||||||
|
|
||||||
|
HelloApi api(&sandbox);
|
||||||
|
std::cout << " 1000 + 337 = " << api.AddTwoIntegers(1000, 337).value()
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
79
sandboxed_api/examples/hello_sapi/hello_transacted.cc
Normal file
79
sandboxed_api/examples/hello_sapi/hello_transacted.cc
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// These are needed for the __NR_xxx syscall numbers
|
||||||
|
#include <linux/audit.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/status/status.h"
|
||||||
|
#include "hello_sapi.sapi.h" // Generated header
|
||||||
|
#include "sandboxed_api/sandbox2/policy.h"
|
||||||
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||||
|
#include "sandboxed_api/transaction.h"
|
||||||
|
#include "sandboxed_api/util/status_macros.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class CustomHelloSandbox : public HelloSandbox {
|
||||||
|
public:
|
||||||
|
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||||
|
sandbox2::PolicyBuilder*) override {
|
||||||
|
// Return a new policy.
|
||||||
|
return sandbox2::PolicyBuilder()
|
||||||
|
.AllowRead()
|
||||||
|
.AllowWrite()
|
||||||
|
.AllowOpen()
|
||||||
|
.AllowSystemMalloc()
|
||||||
|
.AllowHandleSignals()
|
||||||
|
.AllowExit()
|
||||||
|
.AllowStat()
|
||||||
|
.AllowTime()
|
||||||
|
.AllowGetIDs()
|
||||||
|
.AllowGetPIDs()
|
||||||
|
.AllowSyscalls({
|
||||||
|
__NR_tgkill,
|
||||||
|
__NR_recvmsg,
|
||||||
|
__NR_sendmsg,
|
||||||
|
__NR_lseek,
|
||||||
|
__NR_nanosleep,
|
||||||
|
__NR_futex,
|
||||||
|
__NR_close,
|
||||||
|
})
|
||||||
|
.AddFile("/etc/localtime")
|
||||||
|
.BuildOrDie();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Calling into a sandboxee to add two numbers...\n";
|
||||||
|
|
||||||
|
sapi::BasicTransaction transaction(absl::make_unique<CustomHelloSandbox>());
|
||||||
|
|
||||||
|
absl::Status status =
|
||||||
|
transaction.Run([](sapi::Sandbox* sandbox) -> absl::Status {
|
||||||
|
HelloApi api(sandbox);
|
||||||
|
SAPI_ASSIGN_OR_RETURN(int result, api.AddTwoIntegers(1000, 337));
|
||||||
|
std::cout << " 1000 + 337 = " << result << "\n";
|
||||||
|
return absl::OkStatus();
|
||||||
|
});
|
||||||
|
if (!status.ok()) {
|
||||||
|
std::cerr << "Error during sandbox call: " << status.message() << "\n";
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user