From 9ab20c5411fb6b712725e3c8d418484673b64d17 Mon Sep 17 00:00:00 2001 From: Oliver Kunz Date: Wed, 3 May 2023 23:29:00 -0700 Subject: [PATCH] Implements the ability to control who is allowed to enable unrestricted networking. PiperOrigin-RevId: 529309275 Change-Id: Icd88a4469b0c36af96638d44f9e909085c7120d5 --- sandboxed_api/sandbox2/BUILD.bazel | 22 ++++++++++++++ sandboxed_api/sandbox2/CMakeLists.txt | 10 +++++++ .../sandbox2/allow_unrestricted_networking.h | 29 +++++++++++++++++++ sandboxed_api/sandbox2/policybuilder.cc | 13 ++++++--- sandboxed_api/sandbox2/policybuilder.h | 21 ++++++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 sandboxed_api/sandbox2/allow_unrestricted_networking.h diff --git a/sandboxed_api/sandbox2/BUILD.bazel b/sandboxed_api/sandbox2/BUILD.bazel index 40e196d..2adde00 100644 --- a/sandboxed_api/sandbox2/BUILD.bazel +++ b/sandboxed_api/sandbox2/BUILD.bazel @@ -42,6 +42,27 @@ cc_library( visibility = ["//visibility:public"], ) +cc_library( + name = "allow_unrestricted_networking", + hdrs = [ + "allow_unrestricted_networking.h", + ], + copts = sapi_platform_copts(), + visibility = [ + "//sandboxed_api/sandbox2:__pkg__", + "//sandboxed_api/sandbox2/examples/tool:__pkg__", + "//sandboxed_api/sandbox2/performance:__pkg__", + ], +) + +cc_library( + name = "testonly_allow_unrestricted_networking", + testonly = True, + hdrs = ["allow_unrestricted_networking.h"], + copts = sapi_platform_copts(), + visibility = ["//visibility:public"], +) + cc_library( name = "bpfdisassembler", srcs = ["bpfdisassembler.cc"], @@ -519,6 +540,7 @@ cc_library( copts = sapi_platform_copts(), deps = [ ":allow_all_syscalls", + ":allow_unrestricted_networking", ":mounts", ":namespace", ":policy", diff --git a/sandboxed_api/sandbox2/CMakeLists.txt b/sandboxed_api/sandbox2/CMakeLists.txt index de47282..acd8748 100644 --- a/sandboxed_api/sandbox2/CMakeLists.txt +++ b/sandboxed_api/sandbox2/CMakeLists.txt @@ -26,6 +26,15 @@ target_link_libraries(sandbox2_allow_all_syscalls PRIVATE sapi::base ) +# sandboxed_api/sandbox2:allow_unrestricted_networking +add_library(sandbox2_allow_unrestricted_networking ${SAPI_LIB_TYPE} + allow_unrestricted_networking.h +) +add_library(sandbox2::allow_unrestricted_networking ALIAS sandbox2_allow_unrestricted_networking) +target_link_libraries(sandbox2_allow_unrestricted_networking PRIVATE + sapi::base +) + # sandboxed_api/sandbox2:bpfdisassembler add_library(sandbox2_bpfdisassembler ${SAPI_LIB_TYPE} bpfdisassembler.cc @@ -833,6 +842,7 @@ if(BUILD_TESTING AND SAPI_BUILD_TESTING) target_link_libraries(sandbox2_namespace_test PRIVATE absl::strings sandbox2::allow_all_syscalls + sandbox2::allow_unrestricted_networking sapi::config sapi::fileops sandbox2::namespace diff --git a/sandboxed_api/sandbox2/allow_unrestricted_networking.h b/sandboxed_api/sandbox2/allow_unrestricted_networking.h new file mode 100644 index 0000000..c1f3a57 --- /dev/null +++ b/sandboxed_api/sandbox2/allow_unrestricted_networking.h @@ -0,0 +1,29 @@ +// Copyright 2023 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 +// +// https://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_ALLOW_UNRESTRICTED_NETWORKING_H_ +#define SANDBOXED_API_SANDBOX2_ALLOW_UNRESTRICTED_NETWORKING_H_ + +// #include "sandboxed_api/sandbox2/policybuilder.h" + +namespace sandbox2 { + +class UnrestrictedNetworking { + public: + explicit UnrestrictedNetworking() = default; +}; + +} // namespace sandbox2 + +#endif // SANDBOXED_API_SANDBOX2_ALLOW_UNRESTRICTED_NETWORKING_H_ diff --git a/sandboxed_api/sandbox2/policybuilder.cc b/sandboxed_api/sandbox2/policybuilder.cc index 69feb42..9a2dcee 100644 --- a/sandboxed_api/sandbox2/policybuilder.cc +++ b/sandboxed_api/sandbox2/policybuilder.cc @@ -45,6 +45,7 @@ #include "absl/strings/string_view.h" #include "sandboxed_api/config.h" #include "sandboxed_api/sandbox2/allow_all_syscalls.h" +#include "sandboxed_api/sandbox2/allow_unrestricted_networking.h" #include "sandboxed_api/sandbox2/namespace.h" #include "sandboxed_api/sandbox2/policy.h" #include "sandboxed_api/sandbox2/util/bpf_helper.h" @@ -99,6 +100,12 @@ bool IsOnReadOnlyDev(const std::string& path) { } // namespace +PolicyBuilder& PolicyBuilder::Allow(UnrestrictedNetworking tag) { + EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations) + allow_unrestricted_networking_ = true; + return *this; +} + PolicyBuilder& PolicyBuilder::AllowSyscall(uint32_t num) { if (handled_syscalls_.insert(num).second) { user_policy_.insert(user_policy_.end(), {SYSCALL(num, ALLOW)}); @@ -1335,11 +1342,9 @@ PolicyBuilder& PolicyBuilder::AddTmpfs(absl::string_view inside, size_t size) { return *this; } +// Use Allow(UnrestrictedNetworking()) instead. PolicyBuilder& PolicyBuilder::AllowUnrestrictedNetworking() { - EnableNamespaces(); // NOLINT(clang-diagnostic-deprecated-declarations) - allow_unrestricted_networking_ = true; - - return *this; + return Allow(UnrestrictedNetworking()); } PolicyBuilder& PolicyBuilder::SetHostname(absl::string_view hostname) { diff --git a/sandboxed_api/sandbox2/policybuilder.h b/sandboxed_api/sandbox2/policybuilder.h index cd228a4..654525e 100644 --- a/sandboxed_api/sandbox2/policybuilder.h +++ b/sandboxed_api/sandbox2/policybuilder.h @@ -41,6 +41,7 @@ struct bpf_labels; namespace sandbox2 { class AllowAllSyscalls; +class UnrestrictedNetworking; // PolicyBuilder is a helper class to simplify creation of policies. The builder // uses fluent interface for convenience and increased readability of policies. @@ -108,6 +109,26 @@ class PolicyBuilder final { using BpfFunc = const std::function(bpf_labels&)>&; + // Appends code to allow visibility restricted policy functionality. + // + // For example: + // Allow(sandbox2::UnrestrictedNetworking); + // This allows unrestricted network access by not creating a network + // namespace. + // + // Each type T is defined in an individual library and individually visibility + // restricted. + template + PolicyBuilder& Allow(T... tags) { + return (Allow(tags), ...); + } + + // Allows unrestricted access to the network by *not* creating a network + // namespace. Note that this only disables the network namespace. To + // actually allow networking, you would also need to allow networking + // syscalls. Calling this function will enable use of namespaces + PolicyBuilder& Allow(UnrestrictedNetworking tag); + // Appends code to allow a specific syscall PolicyBuilder& AllowSyscall(uint32_t num);