blob: d7fb47f816257e97437c960748444349d8abfc74 [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cros-disks/zip_manager.h"
#include <utility>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include "cros-disks/archive_mounter.h"
#include "cros-disks/error_logger.h"
#include "cros-disks/fuse_mounter.h"
#include "cros-disks/metrics.h"
#include "cros-disks/platform.h"
#include "cros-disks/quote.h"
namespace cros_disks {
namespace {
std::unique_ptr<ArchiveMounter> CreateZipMounter(
Platform* platform,
Metrics* metrics,
brillo::ProcessReaper* process_reaper,
std::vector<gid_t> supplementary_groups) {
OwnerUser run_as;
PCHECK(platform->GetUserAndGroupId("fuse-zip", &run_as.uid, &run_as.gid))
<< "Cannot resolve required user fuse-zip";
const SandboxedExecutable executable = {
base::FilePath("/usr/bin/fuse-zip"),
base::FilePath("/usr/share/policy/fuse-zip-seccomp.policy")};
auto sandbox_factory = std::make_unique<FUSESandboxedProcessFactory>(
platform, std::move(executable), std::move(run_as),
/* has_network_access= */ false, std::move(supplementary_groups));
std::vector<int> password_needed_codes = {
23, // ZIP_ER_BASE + ZIP_ER_ZLIB
36, // ZIP_ER_BASE + ZIP_ER_NOPASSWD
37}; // ZIP_ER_BASE + ZIP_ER_WRONGPASSWD
return std::make_unique<ArchiveMounter>(
platform, process_reaper, "zip", metrics, "FuseZip",
std::move(password_needed_codes), std::move(sandbox_factory));
}
} // namespace
ZipManager::ZipManager(const std::string& mount_root,
Platform* platform,
Metrics* metrics,
brillo::ProcessReaper* process_reaper)
: ArchiveManager(mount_root, platform, metrics, process_reaper),
mounter_(CreateZipMounter(
platform, metrics, process_reaper, GetSupplementaryGroups())) {}
ZipManager::~ZipManager() {
UnmountAll();
}
bool ZipManager::CanMount(const std::string& source_path) const {
base::FilePath name;
return IsInAllowedFolder(source_path) &&
mounter_->CanMount(source_path, {}, &name);
}
std::unique_ptr<MountPoint> ZipManager::DoMount(
const std::string& source_path,
const std::string& /*filesystem_type*/,
const std::vector<std::string>& options,
const base::FilePath& mount_path,
MountOptions* const applied_options,
MountErrorType* const error) {
DCHECK(error);
// MountManager resolves source path to real path before calling DoMount,
// so no symlinks or '..' will be here.
if (!IsInAllowedFolder(source_path)) {
LOG(ERROR) << "Source path " << quote(source_path) << " is not allowed";
*error = MOUNT_ERROR_INVALID_DEVICE_PATH;
return nullptr;
}
return mounter_->Mount(source_path, mount_path, options, error);
}
} // namespace cros_disks