blob: f0ee6e6fcbb47c42f07545130206ea7713c77bba [file] [log] [blame]
// Copyright 2021 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 "dlp/fanotify_watcher.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
#include "base/test/task_environment.h"
#include "gtest/gtest.h"
namespace dlp {
namespace {
bool DoOpen(base::FilePath file_path) {
base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
return file.IsValid();
}
class FileOpenTester {
public:
explicit FileOpenTester(base::FilePath file_path) : file_path_(file_path) {}
~FileOpenTester() = default;
bool CanOpen() {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&DoOpen, file_path_),
base::BindOnce(&FileOpenTester::OnOpenResult, base::Unretained(this)));
run_loop_.Run();
return could_open_;
}
private:
void OnOpenResult(bool result) {
could_open_ = result;
run_loop_.Quit();
}
base::FilePath file_path_;
base::RunLoop run_loop_;
bool could_open_ = false;
};
} // namespace
class FanotifyWatcherTest : public ::testing::Test,
public FanotifyWatcher::Delegate {
public:
FanotifyWatcherTest() = default;
FanotifyWatcherTest(const FanotifyWatcherTest&) = delete;
FanotifyWatcherTest& operator=(const FanotifyWatcherTest&) = delete;
~FanotifyWatcherTest() override = default;
void ProcessFileOpenRequest(
ino_t inode, int pid, base::OnceCallback<void(bool)> callback) override {
counter_++;
std::move(callback).Run(file_open_allowed_);
}
uint32_t counter() const { return counter_; }
protected:
base::test::TaskEnvironment task_environment_;
bool file_open_allowed_ = true;
private:
uint32_t counter_ = 0;
};
TEST_F(FanotifyWatcherTest, RunAsRoot_FileOpenAllowed) {
base::FilePath temp_file;
std::unique_ptr<FanotifyWatcher> watcher =
std::make_unique<FanotifyWatcher>(this);
EXPECT_TRUE(base::CreateTemporaryFile(&temp_file));
watcher->AddWatch(temp_file);
// Open the temporary file.
uint32_t old_counter = counter();
EXPECT_TRUE(FileOpenTester(temp_file).CanOpen());
EXPECT_GE(counter(), old_counter + 1);
}
TEST_F(FanotifyWatcherTest, RunAsRoot_FileOpenNotAllowed) {
base::FilePath temp_file;
std::unique_ptr<FanotifyWatcher> watcher =
std::make_unique<FanotifyWatcher>(this);
EXPECT_TRUE(base::CreateTemporaryFile(&temp_file));
watcher->AddWatch(temp_file);
file_open_allowed_ = false;
// Open the temporary file.
uint32_t old_counter = counter();
EXPECT_FALSE(FileOpenTester(temp_file).CanOpen());
EXPECT_GE(counter(), old_counter + 1);
}
} // namespace dlp