mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-28 12:40:12 +00:00
Prevent accessing incomplete RPCS3.log.gz
Use permissions to make it inaccessible On Windows, autodelete the file Implement fs::unread for this purpose Rename fs::unshare to fs::lock Fix fs::lock correctness
This commit is contained in:
parent
b232409cc5
commit
f66d5adf5f
@ -794,7 +794,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD access = 0;
|
DWORD access = 0;
|
||||||
if (test(mode & fs::read)) access |= GENERIC_READ;
|
if (test(mode & fs::read)) access |= GENERIC_READ;
|
||||||
if (test(mode & fs::write)) access |= test(mode & fs::append) ? FILE_APPEND_DATA : GENERIC_WRITE;
|
if (test(mode & fs::write)) access |= DELETE | (test(mode & fs::append) ? FILE_APPEND_DATA : GENERIC_WRITE);
|
||||||
|
|
||||||
DWORD disp = 0;
|
DWORD disp = 0;
|
||||||
if (test(mode & fs::create))
|
if (test(mode & fs::create))
|
||||||
@ -814,8 +814,13 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
|||||||
disp = test(mode & fs::trunc) ? TRUNCATE_EXISTING : OPEN_EXISTING;
|
disp = test(mode & fs::trunc) ? TRUNCATE_EXISTING : OPEN_EXISTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD share = FILE_SHARE_READ;
|
DWORD share = 0;
|
||||||
if (!test(mode & fs::unshare))
|
if (!test(mode, fs::unread) || !test(mode & fs::write))
|
||||||
|
{
|
||||||
|
share |= FILE_SHARE_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!test(mode, fs::lock + fs::unread) || !test(mode & fs::write))
|
||||||
{
|
{
|
||||||
share |= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
share |= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||||
}
|
}
|
||||||
@ -944,10 +949,17 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
|||||||
|
|
||||||
if (test(mode & fs::append)) flags |= O_APPEND;
|
if (test(mode & fs::append)) flags |= O_APPEND;
|
||||||
if (test(mode & fs::create)) flags |= O_CREAT;
|
if (test(mode & fs::create)) flags |= O_CREAT;
|
||||||
if (test(mode & fs::trunc)) flags |= O_TRUNC;
|
if (test(mode & fs::trunc) && !test(mode, fs::lock + fs::unread)) flags |= O_TRUNC;
|
||||||
if (test(mode & fs::excl)) flags |= O_EXCL;
|
if (test(mode & fs::excl)) flags |= O_EXCL;
|
||||||
|
|
||||||
const int fd = ::open(path.c_str(), flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
int perm = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||||
|
|
||||||
|
if (test(mode & fs::write) && test(mode & fs::unread))
|
||||||
|
{
|
||||||
|
perm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int fd = ::open(path.c_str(), flags, perm);
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
@ -955,13 +967,19 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test(mode & fs::unshare) && ::flock(fd, LOCK_EX | LOCK_NB) != 0)
|
if (test(mode & fs::write) && test(mode, fs::lock + fs::unread) && ::flock(fd, LOCK_EX | LOCK_NB) != 0)
|
||||||
{
|
{
|
||||||
g_tls_error = errno == EWOULDBLOCK ? fs::error::acces : to_error(errno);
|
g_tls_error = errno == EWOULDBLOCK ? fs::error::acces : to_error(errno);
|
||||||
::close(fd);
|
::close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (test(mode & fs::trunc) && test(mode, fs::lock + fs::unread))
|
||||||
|
{
|
||||||
|
// Postpone truncation in order to avoid using O_TRUNC on a locked file
|
||||||
|
::ftruncate(fd, 0);
|
||||||
|
}
|
||||||
|
|
||||||
class unix_file final : public file_base, public get_native_handle
|
class unix_file final : public file_base, public get_native_handle
|
||||||
{
|
{
|
||||||
const int m_fd;
|
const int m_fd;
|
||||||
|
@ -25,7 +25,8 @@ namespace fs
|
|||||||
create,
|
create,
|
||||||
trunc,
|
trunc,
|
||||||
excl,
|
excl,
|
||||||
unshare,
|
lock,
|
||||||
|
unread,
|
||||||
|
|
||||||
__bitset_enum_max
|
__bitset_enum_max
|
||||||
};
|
};
|
||||||
@ -36,7 +37,8 @@ namespace fs
|
|||||||
constexpr auto create = +open_mode::create; // Create file if it doesn't exist
|
constexpr auto create = +open_mode::create; // Create file if it doesn't exist
|
||||||
constexpr auto trunc = +open_mode::trunc; // Clear opened file if it's not empty
|
constexpr auto trunc = +open_mode::trunc; // Clear opened file if it's not empty
|
||||||
constexpr auto excl = +open_mode::excl; // Failure if the file already exists (used with `create`)
|
constexpr auto excl = +open_mode::excl; // Failure if the file already exists (used with `create`)
|
||||||
constexpr auto unshare = +open_mode::unshare; // Prevent opening the file twice
|
constexpr auto lock = +open_mode::lock; // Prevent opening the file more than once
|
||||||
|
constexpr auto unread = +open_mode::unread; // Aggressively prevent reading the opened file (do not use)
|
||||||
|
|
||||||
constexpr auto rewrite = open_mode::write + open_mode::create + open_mode::trunc;
|
constexpr auto rewrite = open_mode::write + open_mode::create + open_mode::trunc;
|
||||||
|
|
||||||
@ -185,7 +187,7 @@ namespace fs
|
|||||||
file() = default;
|
file() = default;
|
||||||
|
|
||||||
// Open file with specified mode
|
// Open file with specified mode
|
||||||
explicit file(const std::string& path, bs_t<open_mode> mode = ::fs::read);
|
explicit file(const std::string& path, bs_t<open_mode> mode = ::fs::read);
|
||||||
|
|
||||||
// Open memory for read
|
// Open memory for read
|
||||||
explicit file(const void* ptr, std::size_t size);
|
explicit file(const void* ptr, std::size_t size);
|
||||||
@ -400,7 +402,7 @@ namespace fs
|
|||||||
{
|
{
|
||||||
m_dir = std::move(ptr);
|
m_dir = std::move(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<dir_base> release()
|
std::unique_ptr<dir_base> release()
|
||||||
{
|
{
|
||||||
return std::move(m_dir);
|
return std::move(m_dir);
|
||||||
|
@ -18,6 +18,7 @@ using namespace std::literals::chrono_literals;
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
@ -309,7 +310,7 @@ logs::file_writer::file_writer(const std::string& name)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!m_file.open(buf_name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
|
if (!m_file.open(buf_name, fs::read + fs::rewrite + fs::lock))
|
||||||
{
|
{
|
||||||
if (fs::g_tls_error == fs::error::acces)
|
if (fs::g_tls_error == fs::error::acces)
|
||||||
{
|
{
|
||||||
@ -361,11 +362,18 @@ logs::file_writer::file_writer(const std::string& name)
|
|||||||
// Actual log file (allowed to fail)
|
// Actual log file (allowed to fail)
|
||||||
m_fout.open(log_name, fs::rewrite);
|
m_fout.open(log_name, fs::rewrite);
|
||||||
|
|
||||||
// Compressed log
|
// Compressed log, make it inaccessible (foolproof)
|
||||||
if (!m_fout2.open(log_name + ".gz", fs::rewrite) || deflateInit2(&m_zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
if (!m_fout2.open(log_name + ".gz", fs::rewrite + fs::unread) || deflateInit2(&m_zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||||
{
|
{
|
||||||
m_fout2.close();
|
m_fout2.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Autodelete compressed log file
|
||||||
|
FILE_DISPOSITION_INFO disp;
|
||||||
|
disp.DeleteFileW = TRUE;
|
||||||
|
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
@ -443,9 +451,16 @@ logs::file_writer::~file_writer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
// Cancel compressed log file autodeletion
|
||||||
|
FILE_DISPOSITION_INFO disp;
|
||||||
|
disp.DeleteFileW = FALSE;
|
||||||
|
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||||
|
|
||||||
UnmapViewOfFile(m_fptr);
|
UnmapViewOfFile(m_fptr);
|
||||||
CloseHandle(m_fmap);
|
CloseHandle(m_fmap);
|
||||||
#else
|
#else
|
||||||
|
// Restore compressed log file permissions
|
||||||
|
::fchmod(m_fout2.get_handle(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
::munmap(m_fptr, s_log_size);
|
::munmap(m_fptr, s_log_size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -591,7 +606,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
|||||||
case level::_uninit: text = u8"· "; break;
|
case level::_uninit: text = u8"· "; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print miscosecond timestamp
|
// Print µs timestamp
|
||||||
const u64 hours = stamp / 3600'000'000;
|
const u64 hours = stamp / 3600'000'000;
|
||||||
const u64 mins = (stamp % 3600'000'000) / 60'000'000;
|
const u64 mins = (stamp % 3600'000'000) / 60'000'000;
|
||||||
const u64 secs = (stamp % 60'000'000) / 1'000'000;
|
const u64 secs = (stamp % 60'000'000) / 1'000'000;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user