From dfda92953abd15aae08addd57e65260a9291078d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Thu, 17 Oct 2013 22:37:32 +0200 Subject: [PATCH] Protect VFS plugin internal files. --- src/Vfs.h | 5 +++++ src/VfsAuthn.cpp | 14 ++++++-------- src/VfsNs.cpp | 25 +++++++++++++++++++------ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/Vfs.h b/src/Vfs.h index c36a0aa..d4eb13c 100644 --- a/src/Vfs.h +++ b/src/Vfs.h @@ -12,6 +12,11 @@ #include +#define VFS_FILE ".#vfs." +#define VFS_FILE_LENGTH 6 +#define VFS_USERS_FILE ".#vfs.users" +#define VFS_GROUPS_FILE ".#vfs.groups" + #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..6c4d054 100644 --- a/src/VfsAuthn.cpp +++ b/src/VfsAuthn.cpp @@ -6,8 +6,6 @@ #include "Vfs.h" #include "VfsAuthn.h" -#define VFS_USERS ".#vfs.users" -#define VFS_GROUPS ".#vfs.groups" #define VFS_UID_START 500 #define VFS_GID_START 500 @@ -330,7 +328,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 +356,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 +391,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 +416,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 b881eb8..74891d4 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -25,6 +25,7 @@ #define VFS_XATTR_TYPE_USER 4 #define VFS_XATTR_TYPE_ALL 7 #define IS_VFS_XATTR(NAME) (strncmp((NAME), VFS_XATTR, VFS_XATTR_LENGTH) == 0) +#define IS_VFS_FILE(NAME) (strncmp((NAME), VFS_FILE, VFS_FILE_LENGTH) == 0) // force everything to current owner for now #define VFS_UID_NONE xStat.stat.st_uid @@ -971,12 +972,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); } @@ -1212,10 +1216,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