summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafal Krypa <r.krypa@samsung.com>2017-12-20 09:10:19 +0100
committerRafal Krypa <r.krypa@samsung.com>2017-12-20 12:01:56 +0100
commitdbabf436a0bab95803c01b1664cb2eb012e5a827 (patch)
tree1cf08af439aa9a5485ea24dcaa367608564d5d14
parent29a98471a593a8d08b5f6a8678242f222854670b (diff)
downloadsecurity-manager-dbabf436a0bab95803c01b1664cb2eb012e5a827.tar.gz
security-manager-dbabf436a0bab95803c01b1664cb2eb012e5a827.tar.bz2
security-manager-dbabf436a0bab95803c01b1664cb2eb012e5a827.zip
Fix MountNS::isPathBound()
Previous implementation of the method checking whether given source path is bind-mounted on a given destination path was unreliable. By careless pattern matching in /proc/self/mountinfo it could easily return false positive (determine that bind mount exists when it doesn't) or false negative (say that bind mount doesn't exist when it does). New implementation relies on calling lstat() on both paths and comparing results. If both paths have the same ID of containing device and the same inode number, they are considered to be bind mounted. Change-Id: I63386dd44f2c1d114705b93a76993a9bc812a90d Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
-rw-r--r--src/common/mount-namespace.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/common/mount-namespace.cpp b/src/common/mount-namespace.cpp
index 88266c5d..51ae5bd4 100644
--- a/src/common/mount-namespace.cpp
+++ b/src/common/mount-namespace.cpp
@@ -212,9 +212,25 @@ int uMount(const Path &target)
bool isPathBound(const Path &what, const Path &where)
{
- std::string line = what + " " + where;
- std::string mountinfo = FS::getTextFileContents("/proc/self/mountinfo");
- return std::string::npos != mountinfo.find(line);
+ struct stat st1, st2;
+ int ret;
+
+ ret = lstat(what.c_str(), &st1);
+ if (ret == -1) {
+ LogError("Unable to stat " << what << " " << GetErrnoString(errno));
+ return false;
+ }
+
+ ret = lstat(where.c_str(), &st2);
+ if (ret == -1) {
+ LogError("Unable to stat " << where << " " << GetErrnoString(errno));
+ return false;
+ }
+
+ // Check whether both paths have the same device ID and inode number
+ // If yes, they point to the same file or directory, which is proof of either
+ // bind mount or a hard link
+ return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
}
} // namespace MountNS