criu/0004-criu-fix-log_keep_err-signal-deadlock.patch
MaSkingx ab5032a5a0
fix log_keep_err signal deadlock
Signed-off-by: MaSkingx <maxin@xfusion.com>
2025-04-18 08:35:05 +00:00

67 lines
1.9 KiB
Diff

From bc1415317379c45b08ac6f8eb98698ca2df9b78c Mon Sep 17 00:00:00 2001
From: Ivan Pravdin <ipravdin.official@gmail.com>
Date: Sat, 22 Mar 2025 19:31:02 -0400
Subject: [PATCH] criu: fix log_keep_err signal deadlock
When using pr_err in signal handler, locking is used
in an unsafe manner. If another signal happens while holding the
lock, deadlock can happen.
To fix this, we can introduce mutex_trylock similar to
pthread_mutex_trylock that returns immediately. Due to the fact
that lock is used only for writing first_err, this change garantees
that deadlock cannot happen.
Fixes: #358
Signed-off-by: Ivan Pravdin <ipravdin.official@gmail.com>
---
criu/log.c | 9 +++++----
include/common/lock.h | 6 ++++++
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/criu/log.c b/criu/log.c
index 89ae8f8205..70e267fd65 100644
--- a/criu/log.c
+++ b/criu/log.c
@@ -132,10 +132,11 @@ static void log_note_err(char *msg)
* anyway, so it doesn't make much sense to try hard
* and optimize this out.
*/
- mutex_lock(&first_err->l);
- if (first_err->s[0] == '\0')
- __strlcpy(first_err->s, msg, sizeof(first_err->s));
- mutex_unlock(&first_err->l);
+ if (mutex_trylock(&first_err->l)) {
+ if (first_err->s[0] == '\0')
+ __strlcpy(first_err->s, msg, sizeof(first_err->s));
+ mutex_unlock(&first_err->l);
+ }
}
}
diff --git a/include/common/lock.h b/include/common/lock.h
index ccfa468b83..4733d72870 100644
--- a/include/common/lock.h
+++ b/include/common/lock.h
@@ -2,6 +2,7 @@
#define __CR_COMMON_LOCK_H__
#include <stdint.h>
+#include <stdbool.h>
#include <linux/futex.h>
#include <sys/time.h>
#include <limits.h>
@@ -162,6 +163,11 @@ static inline void mutex_lock(mutex_t *m)
}
}
+static inline bool mutex_trylock(mutex_t *m)
+{
+ return atomic_inc_return(&m->raw) == 1;
+}
+
static inline void mutex_unlock(mutex_t *m)
{
uint32_t c = 0;