Implement sandbox for OnDeviceTranslation service on Linux
This CL implements sandboxing for OnDeviceTranslation service on Linux. We allow `membarrier` syscall and reading "/sys/devices/system/cpu/possible" inside the sandboxed OnDeviceTranslation service process. Note: The sandboxed OnDeviceTranslation service will crash until https://crbug.com/369491267 is resolved. Bug: 340778819 Change-Id: I289294f35d55bb5dad6bcc0fba422b4077ae2ae7 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5884817 Reviewed-by: Rakina Zata Amni <rakina@chromium.org> Commit-Queue: Tsuyoshi Horo <horo@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org> Reviewed-by: Matthew Denton <mpdenton@chromium.org> Cr-Commit-Position: refs/heads/main@{#1362827}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
f40d5a6605
commit
c640242894
components/services/on_device_translation
content
browser
utility
sandbox/policy
@ -22,6 +22,15 @@ source_set("on_device_translation_service") {
|
||||
"//components/services/on_device_translation/public/mojom",
|
||||
"//mojo/public/cpp/bindings",
|
||||
]
|
||||
|
||||
if (is_linux) {
|
||||
sources += [
|
||||
"sandbox_hook.cc",
|
||||
"sandbox_hook.h",
|
||||
]
|
||||
deps += [ "//sandbox/linux:sandbox_services" ]
|
||||
public_deps += [ "//sandbox/policy" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("unit_tests") {
|
||||
|
8
components/services/on_device_translation/DEPS
Normal file
8
components/services/on_device_translation/DEPS
Normal file
@ -0,0 +1,8 @@
|
||||
specific_include_rules = {
|
||||
"sandbox_hook\.cc": [
|
||||
"+sandbox/linux/syscall_broker/broker_command.h",
|
||||
],
|
||||
"sandbox_hook\.h": [
|
||||
"+sandbox/policy/linux/sandbox_linux.h",
|
||||
],
|
||||
}
|
@ -1 +1,4 @@
|
||||
file://chrome/browser/ai/OWNERS
|
||||
|
||||
per-file sandbox_hook.*=set noparent
|
||||
per-file sandbox_hook.*=file://sandbox/linux/OWNERS
|
||||
|
@ -13,4 +13,8 @@ mojom("mojom") {
|
||||
"//mojo/public/mojom/base",
|
||||
"//sandbox/policy/mojom",
|
||||
]
|
||||
enabled_features = []
|
||||
if (is_linux || is_mac) {
|
||||
enabled_features += [ "is_linux_or_mac" ]
|
||||
}
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ struct OnDeviceTranslationServiceConfig {
|
||||
|
||||
|
||||
// Currently the sandboxing of the On Device Translation service is supported
|
||||
// only on macOS.
|
||||
// only on macOS and Linux.
|
||||
// TODO(crbug.com/340778819): Implement sandboxing on other platforms.
|
||||
[EnableIf=is_mac]
|
||||
[EnableIf=is_linux_or_mac]
|
||||
const sandbox.mojom.Sandbox kOnDeviceTranslationSandbox
|
||||
= sandbox.mojom.Sandbox.kOnDeviceTranslation;
|
||||
[EnableIfNot=is_mac]
|
||||
[EnableIfNot=is_linux_or_mac]
|
||||
const sandbox.mojom.Sandbox kOnDeviceTranslationSandbox
|
||||
= sandbox.mojom.Sandbox.kNoSandbox;
|
||||
|
||||
|
43
components/services/on_device_translation/sandbox_hook.cc
Normal file
43
components/services/on_device_translation/sandbox_hook.cc
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "components/services/on_device_translation/sandbox_hook.h"
|
||||
|
||||
#include "components/services/on_device_translation/translate_kit_client.h"
|
||||
#include "sandbox/linux/syscall_broker/broker_command.h"
|
||||
|
||||
using sandbox::syscall_broker::BrokerFilePermission;
|
||||
using sandbox::syscall_broker::MakeBrokerCommandSet;
|
||||
|
||||
namespace on_device_translation {
|
||||
namespace {
|
||||
|
||||
// Gets the file permissions required by the TranslateKit
|
||||
std::vector<BrokerFilePermission> GetOnDeviceTranslationFilePermissions() {
|
||||
std::vector<BrokerFilePermission> permissions{
|
||||
// Opened for checking the CPU numbers.
|
||||
BrokerFilePermission::ReadOnly("/sys/devices/system/cpu/possible"),
|
||||
};
|
||||
return permissions;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool OnDeviceTranslationSandboxHook(
|
||||
sandbox::policy::SandboxLinux::Options options) {
|
||||
// Call `TranslateKitClient::Get()` to load libtranslatekit.so
|
||||
TranslateKitClient::Get();
|
||||
|
||||
auto* instance = sandbox::policy::SandboxLinux::GetInstance();
|
||||
instance->StartBrokerProcess(MakeBrokerCommandSet({
|
||||
sandbox::syscall_broker::COMMAND_OPEN,
|
||||
}),
|
||||
GetOnDeviceTranslationFilePermissions(),
|
||||
options);
|
||||
instance->EngageNamespaceSandboxIfPossible();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace on_device_translation
|
19
components/services/on_device_translation/sandbox_hook.h
Normal file
19
components/services/on_device_translation/sandbox_hook.h
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef COMPONENTS_SERVICES_ON_DEVICE_TRANSLATION_SANDBOX_HOOK_H_
|
||||
#define COMPONENTS_SERVICES_ON_DEVICE_TRANSLATION_SANDBOX_HOOK_H_
|
||||
|
||||
#include "sandbox/policy/linux/sandbox_linux.h"
|
||||
|
||||
namespace on_device_translation {
|
||||
|
||||
// Opens the TranslateKit binary and grants broker file permissions to the
|
||||
// necessary files required by the binary.
|
||||
bool OnDeviceTranslationSandboxHook(
|
||||
sandbox::policy::SandboxLinux::Options options);
|
||||
|
||||
} // namespace on_device_translation
|
||||
|
||||
#endif // COMPONENTS_SERVICES_ON_DEVICE_TRANSLATION_SANDBOX_HOOK_H_
|
@ -147,6 +147,7 @@ class UtilityProcessSandboxBrowserTest
|
||||
#endif
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
case Sandbox::kVideoEffects:
|
||||
case Sandbox::kOnDeviceTranslation:
|
||||
#endif
|
||||
case Sandbox::kSpeechRecognition: {
|
||||
constexpr int kExpectedPartialSandboxFlags =
|
||||
|
@ -96,7 +96,7 @@ UtilitySandboxedProcessLauncherDelegate::
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
sandbox_type_ == sandbox::mojom::Sandbox::kVideoEffects ||
|
||||
#endif
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
sandbox_type_ == sandbox::mojom::Sandbox::kOnDeviceTranslation ||
|
||||
#endif
|
||||
sandbox_type_ == sandbox::mojom::Sandbox::kAudio ||
|
||||
@ -165,6 +165,7 @@ ZygoteCommunication* UtilitySandboxedProcessLauncherDelegate::GetZygote() {
|
||||
#endif
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
sandbox_type_ == sandbox::mojom::Sandbox::kVideoEffects ||
|
||||
sandbox_type_ == sandbox::mojom::Sandbox::kOnDeviceTranslation ||
|
||||
#endif // BUILDFLAG(IS_LINUX)
|
||||
sandbox_type_ == sandbox::mojom::Sandbox::kSpeechRecognition) {
|
||||
return GetUnsandboxedZygote();
|
||||
|
@ -43,6 +43,7 @@ source_set("utility") {
|
||||
"//build:branding_buildflags",
|
||||
"//build:chromeos_buildflags",
|
||||
"//components/optimization_guide/core:features",
|
||||
"//components/services/on_device_translation:on_device_translation_service",
|
||||
"//components/services/storage",
|
||||
"//components/services/storage/public/mojom",
|
||||
"//content:export",
|
||||
|
@ -3,6 +3,7 @@ include_rules = [
|
||||
"+chromeos/ash/services/ime",
|
||||
"+components/optimization_guide/core/optimization_guide_features.h",
|
||||
"+components/services/storage",
|
||||
"+components/services/on_device_translation",
|
||||
"+content/child",
|
||||
"+content/public/utility",
|
||||
"+content/services",
|
||||
|
@ -102,6 +102,9 @@
|
||||
sandbox::TargetServices* g_utility_target_services = nullptr;
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
#include "components/services/on_device_translation/sandbox_hook.h"
|
||||
#endif // BUILDFLAG(IS_LINUX)
|
||||
namespace content {
|
||||
|
||||
namespace {
|
||||
@ -289,6 +292,12 @@ int UtilityMain(MainFunctionParams parameters) {
|
||||
pre_sandbox_hook =
|
||||
base::BindOnce(&speech::SpeechRecognitionPreSandboxHook);
|
||||
break;
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
case sandbox::mojom::Sandbox::kOnDeviceTranslation:
|
||||
pre_sandbox_hook = base::BindOnce(
|
||||
&on_device_translation::OnDeviceTranslationSandboxHook);
|
||||
break;
|
||||
#endif // BUILDFLAG(IS_LINUX)
|
||||
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
|
||||
case sandbox::mojom::Sandbox::kScreenAI:
|
||||
pre_sandbox_hook =
|
||||
|
@ -74,6 +74,8 @@ component("policy") {
|
||||
"linux/bpf_gpu_policy_linux.h",
|
||||
"linux/bpf_network_policy_linux.cc",
|
||||
"linux/bpf_network_policy_linux.h",
|
||||
"linux/bpf_on_device_translation_policy_linux.cc",
|
||||
"linux/bpf_on_device_translation_policy_linux.h",
|
||||
"linux/bpf_ppapi_policy_linux.cc",
|
||||
"linux/bpf_ppapi_policy_linux.h",
|
||||
"linux/bpf_print_compositor_policy_linux.cc",
|
||||
|
@ -0,0 +1,45 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sandbox/policy/linux/bpf_on_device_translation_policy_linux.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
|
||||
#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
|
||||
#include "sandbox/linux/system_headers/linux_syscalls.h"
|
||||
#include "sandbox/policy/linux/sandbox_linux.h"
|
||||
|
||||
using sandbox::bpf_dsl::Allow;
|
||||
using sandbox::bpf_dsl::Arg;
|
||||
using sandbox::bpf_dsl::If;
|
||||
using sandbox::bpf_dsl::ResultExpr;
|
||||
|
||||
namespace sandbox::policy {
|
||||
|
||||
namespace {
|
||||
static constexpr int kMEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = (1 << 8);
|
||||
}
|
||||
|
||||
ResultExpr OnDeviceTranslationProcessPolicy::EvaluateSyscall(
|
||||
int system_call_number) const {
|
||||
switch (system_call_number) {
|
||||
case __NR_membarrier: {
|
||||
// `membarrier` is used at http://shortn/_d034oISVml (Google-internal).
|
||||
const Arg<int> cmd(0);
|
||||
return If(cmd == kMEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ, Allow())
|
||||
.Else(sandbox::CrashSIGSYS());
|
||||
}
|
||||
default:
|
||||
auto* sandbox_linux = SandboxLinux::GetInstance();
|
||||
if (sandbox_linux->ShouldBrokerHandleSyscall(system_call_number)) {
|
||||
return sandbox_linux->HandleViaBroker(system_call_number);
|
||||
}
|
||||
|
||||
// Default on the content baseline policy.
|
||||
return BPFBasePolicy::EvaluateSyscall(system_call_number);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sandbox::policy
|
@ -0,0 +1,30 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SANDBOX_POLICY_LINUX_BPF_ON_DEVICE_TRANSLATION_POLICY_LINUX_H_
|
||||
#define SANDBOX_POLICY_LINUX_BPF_ON_DEVICE_TRANSLATION_POLICY_LINUX_H_
|
||||
|
||||
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
|
||||
#include "sandbox/policy/linux/bpf_base_policy_linux.h"
|
||||
|
||||
namespace sandbox::policy {
|
||||
|
||||
// This policy is be used by OnDeviceTranslation processe.
|
||||
class SANDBOX_POLICY_EXPORT OnDeviceTranslationProcessPolicy
|
||||
: public BPFBasePolicy {
|
||||
public:
|
||||
OnDeviceTranslationProcessPolicy() = default;
|
||||
~OnDeviceTranslationProcessPolicy() override = default;
|
||||
|
||||
OnDeviceTranslationProcessPolicy(const OnDeviceTranslationProcessPolicy&) =
|
||||
delete;
|
||||
OnDeviceTranslationProcessPolicy& operator=(
|
||||
const OnDeviceTranslationProcessPolicy&) = delete;
|
||||
|
||||
bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override;
|
||||
};
|
||||
|
||||
} // namespace sandbox::policy
|
||||
|
||||
#endif // SANDBOX_POLICY_LINUX_BPF_ON_DEVICE_TRANSLATION_POLICY_LINUX_H_
|
@ -75,6 +75,10 @@
|
||||
#include "sandbox/policy/linux/bpf_hardware_video_decoding_policy_linux.h"
|
||||
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
#include "sandbox/policy/linux/bpf_on_device_translation_policy_linux.h"
|
||||
#endif // BUILDFLAG(IS_LINUX)
|
||||
|
||||
using sandbox::bpf_dsl::Allow;
|
||||
using sandbox::bpf_dsl::ResultExpr;
|
||||
|
||||
@ -214,6 +218,10 @@ std::unique_ptr<BPFBasePolicy> SandboxSeccompBPF::PolicyForSandboxType(
|
||||
return std::make_unique<ServiceProcessPolicy>();
|
||||
case sandbox::mojom::Sandbox::kSpeechRecognition:
|
||||
return std::make_unique<SpeechRecognitionProcessPolicy>();
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
case sandbox::mojom::Sandbox::kOnDeviceTranslation:
|
||||
return std::make_unique<OnDeviceTranslationProcessPolicy>();
|
||||
#endif // BUILDFLAG(IS_LINUX)
|
||||
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
|
||||
case sandbox::mojom::Sandbox::kScreenAI:
|
||||
return std::make_unique<ScreenAIProcessPolicy>();
|
||||
@ -317,6 +325,9 @@ void SandboxSeccompBPF::RunSandboxSanityChecks(
|
||||
case sandbox::mojom::Sandbox::kPrintBackend:
|
||||
#endif
|
||||
case sandbox::mojom::Sandbox::kOnDeviceModelExecution:
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
case sandbox::mojom::Sandbox::kOnDeviceTranslation:
|
||||
#endif // BUILDFLAG(IS_LINUX)
|
||||
case sandbox::mojom::Sandbox::kUtility:
|
||||
case sandbox::mojom::Sandbox::kNoSandbox:
|
||||
case sandbox::mojom::Sandbox::kZygoteIntermediateSandbox:
|
||||
|
@ -168,8 +168,8 @@ enum Sandbox {
|
||||
|
||||
// Hosts On Device Translation service.
|
||||
// Currently the sandboxing of the On Device Translation service is supported
|
||||
// only on macOS.
|
||||
// only on macOS and Linux.
|
||||
// TODO(crbug.com/340778819): Implement sandboxing on other platforms.
|
||||
[EnableIf=is_mac]
|
||||
[EnableIf=is_linux_or_mac]
|
||||
kOnDeviceTranslation,
|
||||
};
|
||||
|
@ -84,7 +84,7 @@ bool IsUnsandboxedSandboxType(Sandbox sandbox_type) {
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
case Sandbox::kVideoEffects:
|
||||
#endif
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
case Sandbox::kOnDeviceTranslation:
|
||||
#endif
|
||||
return false;
|
||||
@ -171,7 +171,7 @@ void SetCommandLineFlagsForSandboxType(base::CommandLine* command_line,
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
case Sandbox::kVideoEffects:
|
||||
#endif
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
case Sandbox::kOnDeviceTranslation:
|
||||
#endif
|
||||
DCHECK(command_line->GetSwitchValueASCII(switches::kProcessType) ==
|
||||
@ -285,7 +285,7 @@ std::string StringFromUtilitySandboxType(Sandbox sandbox_type) {
|
||||
case Sandbox::kVideoEffects:
|
||||
return switches::kVideoEffectsSandbox;
|
||||
#endif
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
case Sandbox::kOnDeviceTranslation:
|
||||
return switches::kOnDeviceTranslationSandbox;
|
||||
#endif
|
||||
@ -404,7 +404,7 @@ sandbox::mojom::Sandbox UtilitySandboxTypeFromString(
|
||||
return Sandbox::kVideoEffects;
|
||||
}
|
||||
#endif
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
if (sandbox_string == switches::kOnDeviceTranslationSandbox) {
|
||||
return Sandbox::kOnDeviceTranslation;
|
||||
}
|
||||
|
@ -71,9 +71,9 @@ const char kLibassistantSandbox[] = "libassistant";
|
||||
#endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
const char kOnDeviceTranslationSandbox[] = "on_device_translation";
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
|
||||
// Flags owned by the service manager sandbox.
|
||||
|
||||
|
@ -74,9 +74,9 @@ SANDBOX_POLICY_EXPORT extern const char kLibassistantSandbox[];
|
||||
#endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
SANDBOX_POLICY_EXPORT extern const char kOnDeviceTranslationSandbox[];
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
|
||||
|
||||
// Flags owned by the service manager sandbox.
|
||||
SANDBOX_POLICY_EXPORT extern const char kAllowSandboxDebugging[];
|
||||
|
Reference in New Issue
Block a user