blob: 55e536bb1a64811773a9965f18c5b0956115c68d [file] [log] [blame]
Anand K Mistry110478e2019-10-29 15:24:11 +11001// Copyright 2019 The Chromium OS 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
5#include "cros-disks/smbfs_helper.h"
6
François Degrosa28315e2020-07-13 00:24:48 +10007#include <utility>
8
Qijiang Fan713061e2021-03-08 15:45:12 +09009#include <base/check.h>
Anand K Mistry110478e2019-10-29 15:24:11 +110010#include <base/files/file_path.h>
11#include <base/logging.h>
12#include <base/strings/string_number_conversions.h>
13#include <base/strings/string_util.h>
14
15#include "cros-disks/fuse_mounter.h"
16#include "cros-disks/mount_options.h"
Anand K Mistry25a5f852020-01-14 17:08:39 +110017#include "cros-disks/mount_point.h"
Anand K Mistry110478e2019-10-29 15:24:11 +110018#include "cros-disks/platform.h"
Sergei Datsenko44612ac2020-11-30 09:35:56 +110019#include "cros-disks/quote.h"
Sergei Datsenko88035aa2020-11-15 00:24:01 +110020#include "cros-disks/sandboxed_process.h"
Anand K Mistry110478e2019-10-29 15:24:11 +110021#include "cros-disks/uri.h"
22
23namespace cros_disks {
24namespace {
25
26const char kUserName[] = "fuse-smbfs";
27const char kHelperTool[] = "/usr/sbin/smbfs";
28const char kType[] = "smbfs";
Anand K Mistry48515af2020-01-10 16:59:41 +110029const char kSeccompPolicyFile[] = "/usr/share/policy/smbfs-seccomp.policy";
Anand K Mistry110478e2019-10-29 15:24:11 +110030
31const char kMojoIdOptionPrefix[] = "mojo_id=";
32const char kDbusSocketPath[] = "/run/dbus";
Anand K Mistrydc599ee2020-04-22 16:55:06 +100033const char kDaemonStorePath[] = "/run/daemon-store/smbfs";
Anand K Mistry110478e2019-10-29 15:24:11 +110034
Sergei Datsenko44612ac2020-11-30 09:35:56 +110035OwnerUser ResolveSmbFsUser(const Platform* platform) {
36 OwnerUser user;
37 PCHECK(platform->GetUserAndGroupId(kUserName, &user.uid, &user.gid));
38 return user;
39}
Anand K Mistry25a5f852020-01-14 17:08:39 +110040
Anand K Mistry110478e2019-10-29 15:24:11 +110041} // namespace
42
43SmbfsHelper::SmbfsHelper(const Platform* platform,
44 brillo::ProcessReaper* process_reaper)
Sergei Datsenko44612ac2020-11-30 09:35:56 +110045 : FUSEMounterHelper(platform,
46 process_reaper,
47 kType,
48 /* nosymfollow= */ true,
49 &sandbox_factory_),
50 sandbox_factory_(platform,
51 SandboxedExecutable{base::FilePath(kHelperTool),
52 base::FilePath(kSeccompPolicyFile)},
53 ResolveSmbFsUser(platform),
54 /* has_network_access= */ true) {}
Anand K Mistry110478e2019-10-29 15:24:11 +110055
56SmbfsHelper::~SmbfsHelper() = default;
57
Sergei Datsenko44612ac2020-11-30 09:35:56 +110058bool SmbfsHelper::CanMount(const std::string& source,
59 const std::vector<std::string>& params,
60 base::FilePath* suggested_name) const {
61 const Uri uri = Uri::Parse(source);
62 if (!uri.valid() || uri.scheme() != kType)
63 return false;
Anand K Mistry110478e2019-10-29 15:24:11 +110064
Sergei Datsenko44612ac2020-11-30 09:35:56 +110065 if (uri.path().empty()) {
66 *suggested_name = base::FilePath(kType);
67 } else {
68 *suggested_name = base::FilePath(uri.path());
69 }
70 return true;
71}
Anand K Mistry110478e2019-10-29 15:24:11 +110072
Sergei Datsenko44612ac2020-11-30 09:35:56 +110073MountErrorType SmbfsHelper::ConfigureSandbox(
74 const std::string& source,
75 const base::FilePath& /*target_path*/,
76 std::vector<std::string> /*params*/,
77 SandboxedProcess* sandbox) const {
78 const Uri uri = Uri::Parse(source);
79 if (!uri.valid() || uri.scheme() != kType || uri.path().empty()) {
François Degrosc309d932021-02-04 15:12:30 +110080 LOG(ERROR) << "Invalid source " << quote(source);
Sergei Datsenko44612ac2020-11-30 09:35:56 +110081 return MOUNT_ERROR_INVALID_DEVICE_PATH;
Anand K Mistry110478e2019-10-29 15:24:11 +110082 }
83
Anand K Mistrydc599ee2020-04-22 16:55:06 +100084 // Bind DBus communication socket and daemon-store into the sandbox.
Sergei Datsenko44612ac2020-11-30 09:35:56 +110085 if (!sandbox->BindMount(kDbusSocketPath, kDbusSocketPath,
86 /* writable= */ true, /* recursive= */ false)) {
87 LOG(ERROR) << "Cannot bind " << quote(kDbusSocketPath);
88 return MOUNT_ERROR_INTERNAL;
89 }
90 // Need to use recursive binding because the daemon-store directory in
91 // their cryptohome is bind mounted inside |kDaemonStorePath|.
92 // TODO(crbug.com/1054705): Pass the user account hash as a mount option
93 // and restrict binding to that specific directory.
94 if (!sandbox->BindMount(kDaemonStorePath, kDaemonStorePath,
95 /* writable= */ true, /* recursive= */ true)) {
96 LOG(ERROR) << "Cannot bind " << quote(kDaemonStorePath);
97 return MOUNT_ERROR_INTERNAL;
98 }
Anand K Mistry110478e2019-10-29 15:24:11 +110099
Sergei Datsenko1bb0bdc2021-02-17 11:26:43 +1100100 std::string options;
101 if (!JoinParamsIntoOptions(
102 {"uid=1000", "gid=1001", kMojoIdOptionPrefix + uri.path()},
103 &options)) {
104 return MOUNT_ERROR_INVALID_MOUNT_OPTIONS;
105 }
Sergei Datsenko44612ac2020-11-30 09:35:56 +1100106 sandbox->AddArgument("-o");
Sergei Datsenko1bb0bdc2021-02-17 11:26:43 +1100107 sandbox->AddArgument(options);
Sergei Datsenko44612ac2020-11-30 09:35:56 +1100108
109 return MOUNT_ERROR_NONE;
Anand K Mistry110478e2019-10-29 15:24:11 +1100110}
111
112} // namespace cros_disks