1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "printing/sandbox/print_backend_sandbox_hook_linux.h"
7 #include "base/base_paths.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/path_service.h"
11 #include "build/build_config.h"
12 #include "printing/buildflags/buildflags.h"
13 #include "sandbox/linux/syscall_broker/broker_command.h"
14 #include "sandbox/linux/syscall_broker/broker_file_permission.h"
15 #include "sandbox/policy/export.h"
16 #include "sandbox/policy/linux/sandbox_linux.h"
18 #if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CUPS)
19 #include "printing/backend/cups_connection_pool.h"
22 using sandbox::syscall_broker::BrokerFilePermission;
23 using sandbox::syscall_broker::MakeBrokerCommandSet;
29 sandbox::syscall_broker::BrokerCommandSet GetPrintBackendBrokerCommandSet() {
30 // Need read access to look at system PPD files.
31 // Need ability to create/write/delete for temporary files in order to
32 // support PPD handling in `printing::ParsePpdCapabilities()`.
33 sandbox::syscall_broker::BrokerCommandSet broker_command_set =
34 MakeBrokerCommandSet({
35 sandbox::syscall_broker::COMMAND_ACCESS,
36 sandbox::syscall_broker::COMMAND_OPEN,
37 sandbox::syscall_broker::COMMAND_READLINK,
38 sandbox::syscall_broker::COMMAND_STAT,
39 sandbox::syscall_broker::COMMAND_UNLINK,
42 return broker_command_set;
45 std::vector<BrokerFilePermission> GetPrintBackendFilePermissions() {
46 #if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CUPS)
47 // No extra permissions required, as the needed socket connections to the CUPS
48 // server are established before entering the sandbox.
49 return std::vector<BrokerFilePermission>();
51 base::FilePath temp_dir_path;
52 CHECK(base::GetTempDir(&temp_dir_path));
53 base::FilePath home_dir_path;
54 CHECK(base::PathService::Get(base::DIR_HOME, &home_dir_path));
55 base::FilePath cups_options_path = home_dir_path.Append(".cups/lpoptions");
57 std::vector<BrokerFilePermission> permissions{
58 // To support reading system PPDs. This list is per the CUPS docs with
59 // macOS-specific paths omitted.
60 // https://www.cups.org/doc/man-cupsd-helper.html
61 BrokerFilePermission::ReadOnlyRecursive("/opt/share/ppd/"),
62 BrokerFilePermission::ReadOnlyRecursive("/usr/local/share/ppd/"),
63 BrokerFilePermission::ReadOnlyRecursive("/usr/share/cups/drv/"),
64 BrokerFilePermission::ReadOnlyRecursive("/usr/share/cups/model/"),
65 BrokerFilePermission::ReadOnlyRecursive("/usr/share/ppd/"),
66 // To support reading user's default printer.
67 // https://www.cups.org/doc/cupspm.html#cupsEnumDests
68 // https://www.cups.org/doc/options.html
69 BrokerFilePermission::ReadOnly(cups_options_path.value()),
70 // To support PPD handling in `printing::ParsePpdCapabilities()`.
71 BrokerFilePermission::ReadWriteCreateTemporary(temp_dir_path.value()),
75 #endif // BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CUPS)
80 bool PrintBackendPreSandboxHook(
81 sandbox::policy::SandboxLinux::Options options) {
82 #if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CUPS)
83 // Create the socket connections to the CUPS server before engaging the
84 // sandbox, since new connections cannot be made after that.
85 CupsConnectionPool::Create();
88 auto* instance = sandbox::policy::SandboxLinux::GetInstance();
90 instance->StartBrokerProcess(
91 GetPrintBackendBrokerCommandSet(), GetPrintBackendFilePermissions(),
92 sandbox::policy::SandboxLinux::PreSandboxHook(), options);
94 instance->EngageNamespaceSandboxIfPossible();
98 } // namespace printing