print_backend_sandbox_hook_linux.cc 4.1 KB

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