mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-17 14:46:13 +03:00
- The shared files Windows implementation introduced in PR #3132 works in multi-process single-threaded contexts but it doesn't work correctly in single-process multi-threaded contexts. - The issue is that the LockFileEx Win32 function works on a per-handle basis. - In a multi-process context, each process will have called SharedFiles::add_new_handler when initializing the SharedFile and obtained a handle, and thus locking will work. - When running ModSecurity in a single process using multiple threads, the initialization of the SharedFile will happen once and the handle will be shared by all threads. Then, if two threads try to write to the same shared file concurrently, they may deadlock as one of them will lock the file (by calling LockFileEx) and then proceed to write to the file. If before writing to the file and unlocking it, another thread calls LockFileEx on the same handle, the attempt to write to the file will lock generating a deadlock. - The new implementation replaces usage of LockFileEx/UnlockFileEx with a named mutex to lock access to the shared file. - A named mutex is used to support multi-process scenarios. - The mutex name is generated using the filename to support multiple shared files (such as that for the debug and audit logs). - This assumes that both process will initialize the SharedFile instance using the same filename (which is expected as they'd be using the same configuration file)
77 lines
1.8 KiB
C++
77 lines
1.8 KiB
C++
/*
|
|
* ModSecurity, http://www.modsecurity.org/
|
|
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
*
|
|
* You may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* If any of the files related to licensing are missing or if you have any
|
|
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
* directly using the email address security@modsecurity.org.
|
|
*
|
|
*/
|
|
|
|
#ifndef SRC_UTILS_SHARED_FILES_H_
|
|
#define SRC_UTILS_SHARED_FILES_H_
|
|
|
|
|
|
#include <stdio.h>
|
|
#ifdef WIN32
|
|
#include <Windows.h>
|
|
#endif
|
|
|
|
#include <unordered_map>
|
|
#include <string>
|
|
|
|
|
|
namespace modsecurity {
|
|
namespace utils {
|
|
|
|
|
|
class SharedFiles {
|
|
public:
|
|
bool open(const std::string& fileName, std::string *error);
|
|
void close(const std::string& fileName);
|
|
bool write(const std::string& fileName, const std::string &msg,
|
|
std::string *error);
|
|
|
|
static SharedFiles& getInstance() {
|
|
static SharedFiles instance;
|
|
return instance;
|
|
}
|
|
|
|
private:
|
|
SharedFiles() = default;
|
|
~SharedFiles() = default;
|
|
|
|
// C++ 03
|
|
// ========
|
|
// Dont forget to declare these two. You want to make sure they
|
|
// are unacceptable otherwise you may accidentally get copies of
|
|
// your singleton appearing.
|
|
SharedFiles(SharedFiles const&) = delete;
|
|
void operator=(SharedFiles const&) = delete;
|
|
|
|
struct handler_info {
|
|
FILE* fp;
|
|
#ifdef WIN32
|
|
HANDLE hMutex;
|
|
#endif
|
|
unsigned int cnt;
|
|
};
|
|
|
|
using handlers_map = std::unordered_map<std::string, handler_info>;
|
|
handlers_map m_handlers;
|
|
|
|
handlers_map::iterator add_new_handler(
|
|
const std::string &fileName, std::string *error);
|
|
};
|
|
|
|
|
|
} // namespace utils
|
|
} // namespace modsecurity
|
|
|
|
#endif // SRC_UTILS_SHARED_FILES_H_
|