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:✌️:RemotePtr` which points to the address of the buffer in the sandboxee's memory space.

PiperOrigin-RevId: 611151615
Change-Id: Ie5012bf17826614395d2056d560689fd9e429d75
main
Oliver Kunz 2024-02-28 10:38:26 -08:00 committed by Copybara-Service
parent 180aa03603
commit 86e356b7ee
5 changed files with 62 additions and 2 deletions

View File

@ -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",
],

View File

@ -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

View File

@ -19,6 +19,7 @@
#include <sys/uio.h>
#include <syscall.h>
#include <cstdint>
#include <cstdio>
#include <initializer_list>
#include <memory>
@ -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<std::unique_ptr<sapi::v::Array<const uint8_t>>>
Sandbox::AllocateAndTransferToSandboxee(absl::Span<const uint8_t> buffer) {
auto sapi_buffer = std::make_unique<sapi::v::Array<const uint8_t>>(
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<std::string> Sandbox::GetCString(const v::RemotePtr& str,
size_t max_length) {
if (!is_active()) {

View File

@ -15,6 +15,7 @@
#ifndef SANDBOXED_API_SANDBOX_H_
#define SANDBOXED_API_SANDBOX_H_
#include <cstdint>
#include <ctime>
#include <initializer_list>
#include <memory>
@ -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<const uint8_t> on success.
absl::StatusOr<std::unique_ptr<sapi::v::Array<const uint8_t>>>
AllocateAndTransferToSandboxee(absl::Span<const uint8_t> buffer);
absl::StatusOr<std::string> GetCString(const v::RemotePtr& str,
size_t max_length = 10ULL
<< 20 /* 10 MiB*/

View File

@ -13,18 +13,24 @@
// limitations under the License.
#include <fcntl.h>
#include <sys/types.h>
#include <cstdint>
#include <memory>
#include <string>
#include <thread> // NOLINT(build/c++11)
#include <vector>
#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<uint8_t> test_string_vector(test_string.begin(),
test_string.end());
absl::Span<uint8_t> buffer_input(
reinterpret_cast<uint8_t*>(test_string_vector.data()),
test_string_vector.size());
std::vector<uint8_t> 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<const uint8_t> sapi_buffer_output(
reinterpret_cast<const uint8_t*>(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