diff options
author | Rafal Krypa <r.krypa@samsung.com> | 2017-12-20 09:10:19 +0100 |
---|---|---|
committer | Rafal Krypa <r.krypa@samsung.com> | 2017-12-20 12:01:56 +0100 |
commit | dbabf436a0bab95803c01b1664cb2eb012e5a827 (patch) | |
tree | 1cf08af439aa9a5485ea24dcaa367608564d5d14 | |
parent | 29a98471a593a8d08b5f6a8678242f222854670b (diff) | |
download | security-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.cpp | 22 |
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 |