From a193cb4ed7f31f5aaf1bdbc37175195d122ffbed Mon Sep 17 00:00:00 2001 From: Kevin Hamacher Date: Fri, 22 Nov 2019 06:44:03 -0800 Subject: [PATCH] sandboxed_api: Expose strlen in the rpc channel PiperOrigin-RevId: 281958333 Change-Id: If15d7d5b915fec3c5521ef53ee44c58d7482d1bc --- sandboxed_api/call.h | 1 + sandboxed_api/client.cc | 11 +++++++++++ sandboxed_api/examples/stringop/lib/BUILD.bazel | 5 +++-- .../examples/stringop/lib/CMakeLists.txt | 1 + sandboxed_api/examples/stringop/lib/stringop.cc | 3 ++- sandboxed_api/examples/stringop/main_stringop.cc | 10 ++++++++++ sandboxed_api/rpcchannel.cc | 15 +++++++++++++++ sandboxed_api/rpcchannel.h | 3 +++ 8 files changed, 46 insertions(+), 3 deletions(-) diff --git a/sandboxed_api/call.h b/sandboxed_api/call.h index a13311f..c3b12f5 100644 --- a/sandboxed_api/call.h +++ b/sandboxed_api/call.h @@ -38,6 +38,7 @@ constexpr uint32_t kMsgSendFd = 0x106; constexpr uint32_t kMsgRecvFd = 0x107; constexpr uint32_t kMsgClose = 0x108; constexpr uint32_t kMsgReallocate = 0x109; +constexpr uint32_t kMsgStrlen = 0x10A; // Return: constexpr uint32_t kMsgReturn = 0x201; diff --git a/sandboxed_api/client.cc b/sandboxed_api/client.cc index 3036ded..75b8baa 100644 --- a/sandboxed_api/client.cc +++ b/sandboxed_api/client.cc @@ -329,6 +329,12 @@ void HandleCloseFd(sandbox2::Comms* comms, int fd_to_close, FuncRet* ret) { ret->success = true; } +void HandleStrlen(sandbox2::Comms* comms, const char* ptr, FuncRet* ret) { + ret->ret_type = v::Type::kInt; + ret->int_val = strlen(ptr); + ret->success = true; +} + template static T BytesAs(const std::vector& bytes) { static_assert(std::is_trivial(), @@ -394,6 +400,11 @@ void ServeRequest(sandbox2::Comms* comms) { VLOG(1) << "Received Client::kMsgClose message"; HandleCloseFd(comms, BytesAs(bytes), &ret); break; + case comms::kMsgStrlen: + VLOG(1) << "Received Client::kMsgStrlen message"; + HandleStrlen(comms, BytesAs(bytes), &ret); + break; + break; default: LOG(FATAL) << "Received unknown tag: " << tag; break; // Not reached diff --git a/sandboxed_api/examples/stringop/lib/BUILD.bazel b/sandboxed_api/examples/stringop/lib/BUILD.bazel index c21c95c..a23e0d7 100644 --- a/sandboxed_api/examples/stringop/lib/BUILD.bazel +++ b/sandboxed_api/examples/stringop/lib/BUILD.bazel @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -licenses(["notice"]) - load("//sandboxed_api/bazel:build_defs.bzl", "sapi_platform_copts") load("//sandboxed_api/bazel:proto.bzl", "sapi_proto_library") load("//sandboxed_api/bazel:sapi.bzl", "sapi_library") +licenses(["notice"]) + sapi_proto_library( name = "stringop_params_proto", srcs = ["stringop_params.proto"], @@ -47,6 +47,7 @@ sapi_library( "pb_reverse_string", "nop", "violate", + "get_raw_c_string", ], input_files = [ "stringop.cc", diff --git a/sandboxed_api/examples/stringop/lib/CMakeLists.txt b/sandboxed_api/examples/stringop/lib/CMakeLists.txt index 3df67ef..733ea60 100644 --- a/sandboxed_api/examples/stringop/lib/CMakeLists.txt +++ b/sandboxed_api/examples/stringop/lib/CMakeLists.txt @@ -51,6 +51,7 @@ add_sapi_library(stringop-sapi pb_reverse_string nop violate + get_raw_c_string INPUTS stringop.cc LIBRARY sapi_stringop LIBRARY_NAME Stringop diff --git a/sandboxed_api/examples/stringop/lib/stringop.cc b/sandboxed_api/examples/stringop/lib/stringop.cc index 5447bf1..826d244 100644 --- a/sandboxed_api/examples/stringop/lib/stringop.cc +++ b/sandboxed_api/examples/stringop/lib/stringop.cc @@ -48,7 +48,6 @@ extern "C" int reverse_string(sapi::LenValStruct* input) { for (size_t i = 0; i < input->size; i++) { new_buf[i] = src_buf[input->size - i - 1]; } - // Free old value. free(input->data); // Replace pointer to our new string. @@ -74,6 +73,8 @@ extern "C" int duplicate_string(sapi::LenValStruct* input) { return 1; } +extern "C" const void* get_raw_c_string() { return "Ten chars."; } + extern "C" void nop() {} extern "C" void violate() { ptrace((__ptrace_request)990, 991, 992, 993); } diff --git a/sandboxed_api/examples/stringop/main_stringop.cc b/sandboxed_api/examples/stringop/main_stringop.cc index 943d408..27728e1 100644 --- a/sandboxed_api/examples/stringop/main_stringop.cc +++ b/sandboxed_api/examples/stringop/main_stringop.cc @@ -130,4 +130,14 @@ TEST(StringopTest, RawStringReversal) { } } +TEST(StringopTest, RawStringLength) { + StringopSapiSandbox sandbox; + ASSERT_THAT(sandbox.Init(), IsOk()); + StringopApi api(&sandbox); + SAPI_ASSERT_OK_AND_ASSIGN(void* target_mem_ptr, api.get_raw_c_string()); + SAPI_ASSERT_OK_AND_ASSIGN(uint64_t len, + sandbox.GetRpcChannel()->Strlen(target_mem_ptr)); + EXPECT_THAT(len, Eq(10)); +} + } // namespace diff --git a/sandboxed_api/rpcchannel.cc b/sandboxed_api/rpcchannel.cc index fb3fe92..7d5d455 100644 --- a/sandboxed_api/rpcchannel.cc +++ b/sandboxed_api/rpcchannel.cc @@ -17,6 +17,7 @@ #include #include "absl/strings/str_cat.h" #include "absl/synchronization/mutex.h" +#include "sandboxed_api/call.h" #include "sandboxed_api/sandbox2/comms.h" #include "sandboxed_api/util/canonical_errors.h" #include "sandboxed_api/util/status_macros.h" @@ -204,4 +205,18 @@ sapi::Status RPCChannel::Close(int remote_fd) { return sapi::OkStatus(); } +sapi::StatusOr RPCChannel::Strlen(void* str) { + absl::MutexLock lock(&mutex_); + if (!comms_->SendTLV(comms::kMsgStrlen, sizeof(str), + reinterpret_cast(&str))) { + return sapi::UnavailableError("Sending TLV value failed"); + } + + SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kInt)); + if (!fret.success) { + return sapi::UnavailableError("Close() failed on the remote side"); + } + return fret.int_val; +} + } // namespace sapi diff --git a/sandboxed_api/rpcchannel.h b/sandboxed_api/rpcchannel.h index 341b7fa..c74763f 100644 --- a/sandboxed_api/rpcchannel.h +++ b/sandboxed_api/rpcchannel.h @@ -60,6 +60,9 @@ class RPCChannel { // Closes fd in sandboxee. sapi::Status Close(int remote_fd); + // Returns length of a null-terminated c-style string (invokes strlen). + sapi::StatusOr Strlen(void* str); + sandbox2::Comms* comms() const { return comms_; } private: