seatbelt_extension.cc 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright 2017 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 "sandbox/mac/seatbelt_extension.h"
  5. #include <ostream>
  6. #include "base/check.h"
  7. #include "base/memory/ptr_util.h"
  8. #include "base/notreached.h"
  9. #include "sandbox/mac/seatbelt_extension_token.h"
  10. // libsandbox private API.
  11. extern "C" {
  12. extern const char* APP_SANDBOX_READ;
  13. extern const char* APP_SANDBOX_READ_WRITE;
  14. int64_t sandbox_extension_consume(const char* token);
  15. int sandbox_extension_release(int64_t handle);
  16. char* sandbox_extension_issue_file(const char* type,
  17. const char* path,
  18. uint32_t flags);
  19. }
  20. namespace sandbox {
  21. SeatbeltExtension::~SeatbeltExtension() {
  22. DCHECK(token_.empty() && handle_ == 0)
  23. << "A SeatbeltExtension must be consumed permanently or revoked.";
  24. }
  25. // static
  26. std::unique_ptr<SeatbeltExtensionToken> SeatbeltExtension::Issue(
  27. SeatbeltExtension::Type type,
  28. const std::string& resource) {
  29. char* token = IssueToken(type, resource);
  30. if (!token)
  31. return nullptr;
  32. return base::WrapUnique(new SeatbeltExtensionToken(token));
  33. }
  34. // static
  35. std::unique_ptr<SeatbeltExtension> SeatbeltExtension::FromToken(
  36. SeatbeltExtensionToken token) {
  37. if (token.token_.empty())
  38. return nullptr;
  39. return base::WrapUnique(new SeatbeltExtension(token.token_));
  40. }
  41. bool SeatbeltExtension::Consume() {
  42. DCHECK(!token_.empty());
  43. handle_ = sandbox_extension_consume(token_.c_str());
  44. return handle_ > 0;
  45. }
  46. bool SeatbeltExtension::ConsumePermanently() {
  47. bool rv = Consume();
  48. handle_ = 0;
  49. token_.clear();
  50. return rv;
  51. }
  52. bool SeatbeltExtension::Revoke() {
  53. int rv = sandbox_extension_release(handle_);
  54. handle_ = 0;
  55. token_.clear();
  56. return rv == 0;
  57. }
  58. SeatbeltExtension::SeatbeltExtension(const std::string& token)
  59. : token_(token), handle_(0) {}
  60. // static
  61. // The token returned by libsandbox is an opaque string generated by the kernel.
  62. // The string contains all the information about the extension (class and
  63. // resource), which is then SHA1 hashed with a salt only known to the kernel.
  64. // In this way, the kernel does not track issued tokens, it merely validates
  65. // them on consumption.
  66. char* SeatbeltExtension::IssueToken(SeatbeltExtension::Type type,
  67. const std::string& resource) {
  68. switch (type) {
  69. case FILE_READ:
  70. return sandbox_extension_issue_file(APP_SANDBOX_READ, resource.c_str(),
  71. 0);
  72. case FILE_READ_WRITE:
  73. return sandbox_extension_issue_file(APP_SANDBOX_READ_WRITE,
  74. resource.c_str(), 0);
  75. default:
  76. NOTREACHED();
  77. return nullptr;
  78. }
  79. }
  80. } // namespace sandbox