From 0b6b3495b6c0242855ffb6c8c5febce2c6138672 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 19 Oct 2013 21:15:58 +0200 Subject: [PATCH] Protect VFS plugin internal files. --- src/Vfs.h | 3 +++ src/VfsAuthn.cpp | 16 ++++++++-------- src/VfsNs.cpp | 26 ++++++++++++++++++++------ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/Vfs.h b/src/Vfs.h index 89e366e..5888334 100644 --- a/src/Vfs.h +++ b/src/Vfs.h @@ -12,6 +12,9 @@ #include +#define VFS_FILE ".#vfs." +#define VFS_FILE_LENGTH 6 + #ifdef DEBUG #ifdef __GNUC__ #define debug(MSG, ARGS...) syslog(LOG_DEBUG, "%s::%s(): " MSG, getImplId().c_str(), __func__, ##ARGS) diff --git a/src/VfsAuthn.cpp b/src/VfsAuthn.cpp index cf2823b..a9e37c2 100644 --- a/src/VfsAuthn.cpp +++ b/src/VfsAuthn.cpp @@ -6,8 +6,8 @@ #include "Vfs.h" #include "VfsAuthn.h" -#define VFS_USERS ".#vfs.users" -#define VFS_GROUPS ".#vfs.groups" +#define VFS_USERS_FILE ".#vfs.users" +#define VFS_GROUPS_FILE ".#vfs.groups" #define VFS_UID_START 500 #define VFS_GID_START 500 @@ -330,7 +330,7 @@ void VfsAuthn::vfsReload() throw (DmException) { this->users_.clear(); this->uids_.clear(); - f = new std::ifstream((this->prefix_ + VFS_USERS).c_str()); + f = new std::ifstream((this->prefix_ + VFS_USERS_FILE).c_str()); if (f->is_open()) { n = 0; while (std::getline(*f, entrypp)) { @@ -358,7 +358,7 @@ void VfsAuthn::vfsReload() throw (DmException) { this->groups_.clear(); this->gids_.clear(); - f = new std::ifstream((this->prefix_ + VFS_GROUPS).c_str()); + f = new std::ifstream((this->prefix_ + VFS_GROUPS_FILE).c_str()); if (f->is_open()) { n = 0; while (std::getline(*f, entrypp)) { @@ -393,8 +393,8 @@ void VfsAuthn::vfsSaveUsers() throw (DmException) { if (this->noSync_) return; - name = this->prefix_ + VFS_USERS; - newName = this->prefix_ + ".new" + VFS_USERS; + name = this->prefix_ + VFS_USERS_FILE; + newName = this->prefix_ + ".new" + VFS_USERS_FILE; f.open(newName.c_str()); if (!f) @@ -418,8 +418,8 @@ void VfsAuthn::vfsSaveGroups() throw (DmException) { if (this->noSync_) return; - name = this->prefix_ + VFS_GROUPS; - newName = this->prefix_ + ".new" + VFS_GROUPS; + name = this->prefix_ + VFS_GROUPS_FILE; + newName = this->prefix_ + ".new" + VFS_GROUPS_FILE; f.open(newName.c_str()); if (!f) diff --git a/src/VfsNs.cpp b/src/VfsNs.cpp index efdc8a2..ff3d9b7 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -17,6 +17,8 @@ #include "Vfs.h" #include "VfsNs.h" +#define IS_VFS_FILE(NAME) (strncmp((NAME), VFS_FILE, VFS_FILE_LENGTH) == 0) + using namespace dmlite; @@ -729,12 +731,15 @@ struct dirent* VfsCatalog::readDir(Directory* dir) throw (DmException) if (privateDir == NULL) vfsThrow(DMLITE_SYSERR(EFAULT), "Tried to read a null directory"); - errno = 0; - ent = readdir(privateDir->dir); - if (!ent && errno) - vfsThrow(errno, "readdir() on '%s' failed", privateDir->path.c_str()); + do { + errno = 0; + ent = readdir(privateDir->dir); + if (!ent && errno) + vfsThrow(errno, "readdir() on '%s' failed", privateDir->path.c_str()); + + debug("result %s", ent ? ent->d_name : "(null)"); + } while (ent && IS_VFS_FILE(ent->d_name)); - debug("result %s", ent ? ent->d_name : "(null)"); return static_cast(ent); } @@ -991,10 +996,19 @@ const std::string VfsCatalog::getLocalPath(const std::string &path) { /// int VfsCatalog::vfsCheckPermissions(const std::string& path, mode_t mode) { int ret = 1; + const char *name; + // only configured subjects (user names) if (this->allowCurrent) { if ((mode & S_IWRITE) != 0) ret = this->allowWriteCurrent ? 0 : 1; - else return 0; + else ret = 0; + } + + // forbid files starting VFS_FILE + if (ret == 0) { + name = path.c_str(); + if (name[0] == '/') name++; + ret = (IS_VFS_FILE(name)); } return ret; -- 1.8.2.3