mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
Replaced log locking using mutex with fcntl lock
When reloading Nginx, there is a race condition which is visible under high load. As the logging mutex is shared between multiple workers, when a worker is sent a stop signal during a reload, and the log mutex is held, write() will never return, which means that the mutex will never unlock. As other workers share this mutex, they will deadlock. fcntl does not suffer from this issue.
This commit is contained in:
parent
5a4ada39bc
commit
3d2030426c
@ -104,7 +104,6 @@ std::pair<msc_file_handler *, FILE *> SharedFiles::add_new_handler(
|
|||||||
|
|
||||||
if (toBeCreated) {
|
if (toBeCreated) {
|
||||||
memset(new_debug_log, '\0', sizeof(msc_file_handler_t));
|
memset(new_debug_log, '\0', sizeof(msc_file_handler_t));
|
||||||
pthread_mutex_init(&new_debug_log->lock, NULL);
|
|
||||||
new_debug_log->shm_id_structure = shm_id;
|
new_debug_log->shm_id_structure = shm_id;
|
||||||
memcpy(new_debug_log->file_name, fileName.c_str(), fileName.size());
|
memcpy(new_debug_log->file_name, fileName.c_str(), fileName.size());
|
||||||
new_debug_log->file_name[fileName.size()] = '\0';
|
new_debug_log->file_name[fileName.size()] = '\0';
|
||||||
@ -222,6 +221,7 @@ bool SharedFiles::write(const std::string& fileName,
|
|||||||
std::pair<msc_file_handler *, FILE *> a;
|
std::pair<msc_file_handler *, FILE *> a;
|
||||||
std::string lmsg = msg;
|
std::string lmsg = msg;
|
||||||
size_t wrote;
|
size_t wrote;
|
||||||
|
struct flock lock{};
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
a = find_handler(fileName);
|
a = find_handler(fileName);
|
||||||
@ -230,15 +230,21 @@ bool SharedFiles::write(const std::string& fileName,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&a.first->lock);
|
//Exclusively lock whole file
|
||||||
wrote = fwrite(reinterpret_cast<const char *>(lmsg.c_str()), 1,
|
lock.l_start = lock.l_len = lock.l_whence = 0;
|
||||||
lmsg.size(), a.second);
|
lock.l_type = F_WRLCK;
|
||||||
|
fcntl(fileno(a.second), F_SETLKW, &lock);
|
||||||
|
|
||||||
|
wrote = fwrite(lmsg.c_str(), 1, lmsg.size(), a.second);
|
||||||
if (wrote < msg.size()) {
|
if (wrote < msg.size()) {
|
||||||
error->assign("failed to write: " + fileName);
|
error->assign("failed to write: " + fileName);
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
fflush(a.second);
|
fflush(a.second);
|
||||||
pthread_mutex_unlock(&a.first->lock);
|
|
||||||
|
//Remove exclusive lock
|
||||||
|
lock.l_type = F_UNLCK;
|
||||||
|
fcntl(fileno(a.second), F_SETLKW, &lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ namespace utils {
|
|||||||
|
|
||||||
typedef struct msc_file_handler {
|
typedef struct msc_file_handler {
|
||||||
int shm_id_structure;
|
int shm_id_structure;
|
||||||
pthread_mutex_t lock;
|
|
||||||
char file_name[];
|
char file_name[];
|
||||||
} msc_file_handler_t;
|
} msc_file_handler_t;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user