mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-15 02:00:41 +02:00
FileManagement: Hide the FEX RootFS fd from /proc/self/fd take 2
Apparently Chromium/CEF can chroot or otherwise sandbox the filesystem away before forking and checking for directory FDs, making /proc inaccessible, which means we can't stat it for our inode check, breaking the hiding. So, double down on things and do what Chromium does: open an fd to /proc ahead of time, so that continues to work. Then we use it to update the inode of our RootFS fd instead, and finally, also do the /proc fd itself to hide that one too. We also don't need to check the st_dev of /proc more than once, since that's not expected to change anyway. Fixes cefsimple.
This commit is contained in:
1 parent
e675f4241a
commit
73ffaa1e18
2 files changed
+28
-7
No files matched your search
@@ -322,6 +322,16 @@ FileManager::FileManager(FEXCore::Context::Context* ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// Keep an fd open for /proc, to bypass chroot-style sandboxes
|
||||
ProcFD = open("/proc", O_RDONLY | O_CLOEXEC);
|
||||
|
||||
// Track the st_dev of /proc, to check for inode equality
|
||||
struct stat Buffer;
|
||||
auto Result = fstat(ProcFD, &Buffer);
|
||||
if (Result >= 0) {
|
||||
ProcFSDev = Buffer.st_dev;
|
||||
}
|
||||
|
||||
UpdatePID(::getpid());
|
||||
}
|
||||
|
||||
@@ -998,30 +1008,39 @@ void FileManager::UpdatePID(uint32_t PID) {
|
||||
CurrentPID = PID;
|
||||
|
||||
// Track the inode of /proc/self/fd/<RootFSFD>, to be able to hide it
|
||||
auto FDpath = fextl::fmt::format("/proc/self/fd/{}", RootFSFD);
|
||||
auto FDpath = fextl::fmt::format("self/fd/{}", RootFSFD);
|
||||
struct stat Buffer {};
|
||||
int Result = fstatat(AT_FDCWD, FDpath.c_str(), &Buffer, AT_SYMLINK_NOFOLLOW);
|
||||
int Result = fstatat(ProcFD, FDpath.c_str(), &Buffer, AT_SYMLINK_NOFOLLOW);
|
||||
if (Result >= 0) {
|
||||
RootFSFDInode = Buffer.st_ino;
|
||||
} else {
|
||||
// Probably in a strict sandbox
|
||||
RootFSFDInode = 0;
|
||||
ProcFDInode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Track the st_dev of /proc, to check for inode equality
|
||||
Result = stat("/proc/self", &Buffer);
|
||||
// And track the ProcFSFD itself
|
||||
FDpath = fextl::fmt::format("self/fd/{}", ProcFD);
|
||||
Result = fstatat(ProcFD, FDpath.c_str(), &Buffer, AT_SYMLINK_NOFOLLOW);
|
||||
if (Result >= 0) {
|
||||
ProcFSDev = Buffer.st_dev;
|
||||
ProcFDInode = Buffer.st_ino;
|
||||
} else {
|
||||
// ??
|
||||
ProcFDInode = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool FileManager::IsRootFSFD(int dirfd, uint64_t inode) {
|
||||
|
||||
// Check if we have to hide this entry
|
||||
if (inode == RootFSFDInode) {
|
||||
if (inode == RootFSFDInode || inode == ProcFDInode) {
|
||||
struct stat Buffer;
|
||||
if (fstat(dirfd, &Buffer) >= 0) {
|
||||
if (Buffer.st_dev == ProcFSDev) {
|
||||
LogMan::Msg::DFmt("Hiding directory entry for RootFSFD");
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,9 @@ private:
|
||||
FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE);
|
||||
uint32_t CurrentPID {};
|
||||
int RootFSFD {AT_FDCWD};
|
||||
int ProcFD {0};
|
||||
int64_t RootFSFDInode = 0;
|
||||
int64_t ProcFDInode = 0;
|
||||
dev_t ProcFSDev;
|
||||
};
|
||||
} // namespace FEX::HLE
|
||||
Reference in new issue
Block a user