From 2a428d20ce17da5c84f1edb3461ca86ad36f3023 Mon Sep 17 00:00:00 2001 From: Ivan Pravdin 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 --- 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 89ae8f820..70e267fd6 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 ccfa468b8..4733d7287 100644 --- a/include/common/lock.h +++ b/include/common/lock.h @@ -2,6 +2,7 @@ #define __CR_COMMON_LOCK_H__ #include +#include #include #include #include @@ -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;