diff --git a/env/env_posix.cc b/env/env_posix.cc index 2fa1daed2..2d1985f68 100644 --- a/env/env_posix.cc +++ b/env/env_posix.cc @@ -74,6 +74,10 @@ ThreadStatusUpdater* CreateThreadStatusUpdater() { return new ThreadStatusUpdater(); } +inline mode_t GetDBFileMode(bool allow_non_owner_access) { + return allow_non_owner_access ? 0644 : 0600; +} + // list of pathnames that are locked static std::set lockedFiles; static port::Mutex mutex_lockedFiles; @@ -167,7 +171,7 @@ class PosixEnv : public Env { do { IOSTATS_TIMER_GUARD(open_nanos); - fd = open(fname.c_str(), flags, 0644); + fd = open(fname.c_str(), flags, GetDBFileMode(allow_non_owner_access_)); } while (fd < 0 && errno == EINTR); if (fd < 0) { return IOError("While opening a file for sequentially reading", fname, @@ -217,7 +221,7 @@ class PosixEnv : public Env { do { IOSTATS_TIMER_GUARD(open_nanos); - fd = open(fname.c_str(), flags, 0644); + fd = open(fname.c_str(), flags, GetDBFileMode(allow_non_owner_access_)); } while (fd < 0 && errno == EINTR); if (fd < 0) { return IOError("While open a file for random read", fname, errno); @@ -288,7 +292,7 @@ class PosixEnv : public Env { do { IOSTATS_TIMER_GUARD(open_nanos); - fd = open(fname.c_str(), flags, 0644); + fd = open(fname.c_str(), flags, GetDBFileMode(allow_non_owner_access_)); } while (fd < 0 && errno == EINTR); if (fd < 0) { @@ -376,7 +380,8 @@ class PosixEnv : public Env { do { IOSTATS_TIMER_GUARD(open_nanos); - fd = open(old_fname.c_str(), flags, 0644); + fd = open(old_fname.c_str(), flags, + GetDBFileMode(allow_non_owner_access_)); } while (fd < 0 && errno == EINTR); if (fd < 0) { s = IOError("while reopen file for write", fname, errno); @@ -436,7 +441,8 @@ class PosixEnv : public Env { int fd = -1; while (fd < 0) { IOSTATS_TIMER_GUARD(open_nanos); - fd = open(fname.c_str(), O_CREAT | O_RDWR, 0644); + fd = open(fname.c_str(), O_CREAT | O_RDWR, + GetDBFileMode(allow_non_owner_access_)); if (fd < 0) { // Error while opening the file if (errno == EINTR) { @@ -789,6 +795,11 @@ class PosixEnv : public Env { return thread_pools_[pri].GetBackgroundThreads(); } + virtual Status SetAllowNonOwnerAccess(bool allow_non_owner_access) override { + allow_non_owner_access_ = allow_non_owner_access; + return Status::OK(); + } + // Allow increasing the number of worker threads. virtual void IncBackgroundThreadsIfNeeded(int num, Priority pri) override { assert(pri >= Priority::BOTTOM && pri <= Priority::HIGH); @@ -888,13 +899,17 @@ class PosixEnv : public Env { std::vector thread_pools_; pthread_mutex_t mu_; std::vector threads_to_join_; + // If true, allow non owner read access for db files. Otherwise, non-owner + // has no access to db files. + bool allow_non_owner_access_; }; PosixEnv::PosixEnv() : checkedDiskForMmap_(false), forceMmapOff_(false), page_size_(getpagesize()), - thread_pools_(Priority::TOTAL) { + thread_pools_(Priority::TOTAL), + allow_non_owner_access_(true) { ThreadPoolImpl::PthreadCall("mutex_init", pthread_mutex_init(&mu_, nullptr)); for (int pool_id = 0; pool_id < Env::Priority::TOTAL; ++pool_id) { thread_pools_[pool_id].SetThreadPriority( diff --git a/env/env_test.cc b/env/env_test.cc index 237d7ef9c..2020b9460 100644 --- a/env/env_test.cc +++ b/env/env_test.cc @@ -166,6 +166,40 @@ TEST_F(EnvPosixTest, AreFilesSame) { } #endif +#ifdef OS_LINUX +TEST_F(EnvPosixTest, FilePermission) { + // Only works for Linux environment + if (env_ == Env::Default()) { + EnvOptions soptions; + std::vector fileNames { + test::TmpDir(env_) + "/testfile", test::TmpDir(env_) + "/testfile1"}; + unique_ptr wfile; + ASSERT_OK(env_->NewWritableFile(fileNames[0], &wfile, soptions)); + unique_ptr rwfile; + ASSERT_OK(env_->NewRandomRWFile(fileNames[1], &rwfile, soptions)); + + struct stat sb; + for (const auto& filename : fileNames) { + if (::stat(filename.c_str(), &sb) == 0) { + ASSERT_EQ(sb.st_mode & 0777, 0644); + } + env_->DeleteFile(filename); + } + + env_->SetAllowNonOwnerAccess(false); + ASSERT_OK(env_->NewWritableFile(fileNames[0], &wfile, soptions)); + ASSERT_OK(env_->NewRandomRWFile(fileNames[1], &rwfile, soptions)); + + for (const auto& filename : fileNames) { + if (::stat(filename.c_str(), &sb) == 0) { + ASSERT_EQ(sb.st_mode & 0777, 0600); + } + env_->DeleteFile(filename); + } + } +} +#endif + TEST_P(EnvPosixTestWithParam, UnSchedule) { std::atomic called(false); env_->SetBackgroundThreads(1, Env::LOW); diff --git a/include/rocksdb/env.h b/include/rocksdb/env.h index 81e58df2b..866740641 100644 --- a/include/rocksdb/env.h +++ b/include/rocksdb/env.h @@ -383,6 +383,10 @@ class Env { virtual void SetBackgroundThreads(int number, Priority pri = LOW) = 0; virtual int GetBackgroundThreads(Priority pri = LOW) = 0; + virtual Status SetAllowNonOwnerAccess(bool /*allow_non_owner_access*/) { + return Status::NotSupported("Not supported."); + } + // Enlarge number of background worker threads of a specific thread pool // for this environment if it is smaller than specified. 'LOW' is the default // pool. @@ -1074,6 +1078,10 @@ class EnvWrapper : public Env { return target_->GetBackgroundThreads(pri); } + Status SetAllowNonOwnerAccess(bool allow_non_owner_access) override { + return target_->SetAllowNonOwnerAccess(allow_non_owner_access); + } + void IncBackgroundThreadsIfNeeded(int num, Priority pri) override { return target_->IncBackgroundThreadsIfNeeded(num, pri); }