From 86e356b7ee4712aa203e4e6b0deb884c0a3c9981 Mon Sep 17 00:00:00 2001 From: Oliver Kunz Date: Wed, 28 Feb 2024 10:38:26 -0800 Subject: [PATCH] Add `Sandbox::AllocateAndTransferToSandboxee` utility function. Create a utility function to copy a hostcode local buffer into the sandboxee. This combines the following steps into one API call: 1) Create a SAPI variable backed with the hostcode local buffer 2) Allocate the SAPI variable in the sandboxee's memory space 3) Transfer the SAPI variable into the sandboxee's memory space The function returns a `std::unique_ptr` wrapped `sapi::v::RemotePtr` which points to the address of the buffer in the sandboxee's memory space. PiperOrigin-RevId: 611151615 Change-Id: Ie5012bf17826614395d2056d560689fd9e429d75 --- sandboxed_api/BUILD.bazel | 7 +++++-- sandboxed_api/CMakeLists.txt | 1 + sandboxed_api/sandbox.cc | 14 ++++++++++++++ sandboxed_api/sandbox.h | 8 ++++++++ sandboxed_api/sapi_test.cc | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/sandboxed_api/BUILD.bazel b/sandboxed_api/BUILD.bazel index d255a21..a7a13c5 100644 --- a/sandboxed_api/BUILD.bazel +++ b/sandboxed_api/BUILD.bazel @@ -86,10 +86,8 @@ cc_library( "//sandboxed_api/util:raw_logging", "//sandboxed_api/util:runfiles", "//sandboxed_api/util:status", - "@com_google_absl//absl/base", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:dynamic_annotations", - "@com_google_absl//absl/base:log_severity", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/log", "@com_google_absl//absl/log:check", @@ -100,6 +98,7 @@ cc_library( "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", + "@com_google_absl//absl/types:span", ], ) @@ -208,13 +207,17 @@ cc_test( deps = [ ":sapi", ":testing", + ":vars", "//sandboxed_api/examples/stringop:stringop-sapi", "//sandboxed_api/examples/stringop:stringop_params_cc_proto", "//sandboxed_api/examples/sum:sum-sapi", "//sandboxed_api/util:status_matchers", + "@com_google_absl//absl/log", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", + "@com_google_absl//absl/types:span", "@com_google_benchmark//:benchmark", "@com_google_googletest//:gtest_main", ], diff --git a/sandboxed_api/CMakeLists.txt b/sandboxed_api/CMakeLists.txt index 11eba3c..940f53c 100644 --- a/sandboxed_api/CMakeLists.txt +++ b/sandboxed_api/CMakeLists.txt @@ -76,6 +76,7 @@ target_link_libraries(sapi_sapi absl::flat_hash_map absl::log absl::log_globals + absl::span absl::status absl::statusor absl::str_format diff --git a/sandboxed_api/sandbox.cc b/sandboxed_api/sandbox.cc index 88b2696..34ffe5b 100644 --- a/sandboxed_api/sandbox.cc +++ b/sandboxed_api/sandbox.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -33,7 +34,9 @@ #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" #include "absl/time/time.h" +#include "absl/types/span.h" #include "sandboxed_api/config.h" #include "sandboxed_api/embed_file.h" #include "sandboxed_api/rpcchannel.h" @@ -48,6 +51,8 @@ #include "sandboxed_api/util/raw_logging.h" #include "sandboxed_api/util/runfiles.h" #include "sandboxed_api/util/status_macros.h" +#include "sandboxed_api/var_array.h" +#include "sandboxed_api/var_ptr.h" namespace sapi { @@ -422,6 +427,15 @@ absl::Status Sandbox::TransferFromSandboxee(v::Var* var) { return var->TransferFromSandboxee(rpc_channel(), pid()); } +absl::StatusOr>> +Sandbox::AllocateAndTransferToSandboxee(absl::Span buffer) { + auto sapi_buffer = std::make_unique>( + buffer.data(), buffer.size()); + SAPI_RETURN_IF_ERROR(Allocate(sapi_buffer.get(), /*automatic_free=*/true)); + SAPI_RETURN_IF_ERROR(TransferToSandboxee(sapi_buffer.get())); + return sapi_buffer; +} + absl::StatusOr Sandbox::GetCString(const v::RemotePtr& str, size_t max_length) { if (!is_active()) { diff --git a/sandboxed_api/sandbox.h b/sandboxed_api/sandbox.h index 74a25ba..7c41921 100644 --- a/sandboxed_api/sandbox.h +++ b/sandboxed_api/sandbox.h @@ -15,6 +15,7 @@ #ifndef SANDBOXED_API_SANDBOX_H_ #define SANDBOXED_API_SANDBOX_H_ +#include #include #include #include @@ -28,6 +29,7 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/time/time.h" +#include "absl/types/span.h" #include "sandboxed_api/config.h" #include "sandboxed_api/rpcchannel.h" #include "sandboxed_api/sandbox2/client.h" @@ -124,6 +126,12 @@ class Sandbox { // SAPI_RETURN_IF_ERROR(sandbox.TransferFromSandboxee(&sapi_buffer)); absl::Status TransferFromSandboxee(v::Var* var); + // Allocates and transfers a buffer to the sandboxee's address space from the + // hostcode. Returns a status on failure, or a unique_ptr to + // sapi::v::Array on success. + absl::StatusOr>> + AllocateAndTransferToSandboxee(absl::Span buffer); + absl::StatusOr GetCString(const v::RemotePtr& str, size_t max_length = 10ULL << 20 /* 10 MiB*/ diff --git a/sandboxed_api/sapi_test.cc b/sandboxed_api/sapi_test.cc index 6aa25ab..31b9650 100644 --- a/sandboxed_api/sapi_test.cc +++ b/sandboxed_api/sapi_test.cc @@ -13,18 +13,24 @@ // limitations under the License. #include +#include +#include #include #include #include // NOLINT(build/c++11) +#include #include "benchmark/benchmark.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "absl/time/time.h" +#include "absl/types/span.h" #include "sandboxed_api/examples/stringop/stringop-sapi.sapi.h" #include "sandboxed_api/examples/stringop/stringop_params.pb.h" #include "sandboxed_api/examples/sum/sum-sapi.sapi.h" @@ -32,15 +38,18 @@ #include "sandboxed_api/testing.h" #include "sandboxed_api/transaction.h" #include "sandboxed_api/util/status_matchers.h" +#include "sandboxed_api/var_array.h" namespace sapi { namespace { using ::sapi::IsOk; using ::sapi::StatusIs; +using ::testing::ContainerEq; using ::testing::Eq; using ::testing::Gt; using ::testing::HasSubstr; +using ::testing::NotNull; // Functions that will be used during the benchmarks: @@ -303,5 +312,30 @@ TEST(SandboxTest, UseUnotifyMonitor) { EXPECT_THAT(result, Eq(3)); } +TEST(SandboxTest, AllocateAndTransferTest) { + std::string test_string("This is a test"); + std::vector test_string_vector(test_string.begin(), + test_string.end()); + + absl::Span buffer_input( + reinterpret_cast(test_string_vector.data()), + test_string_vector.size()); + std::vector buffer_output(test_string_vector.size()); + + SumSandbox sandbox; + ASSERT_THAT(sandbox.Init(), IsOk()); + SumApi api(&sandbox); + + SAPI_ASSERT_OK_AND_ASSIGN( + auto sapi_array, sandbox.AllocateAndTransferToSandboxee(buffer_input)); + ASSERT_THAT(sapi_array, NotNull()); + sapi::v::Array sapi_buffer_output( + reinterpret_cast(buffer_output.data()), + buffer_output.size()); + sapi_buffer_output.SetRemote(sapi_array->GetRemote()); + ASSERT_THAT(sandbox.TransferFromSandboxee(&sapi_buffer_output), IsOk()); + EXPECT_THAT(test_string_vector, ContainerEq(buffer_output)); +} + } // namespace } // namespace sapi