File 0060-MC-races.patch of Package sssd.39283
From 2167cdfa5a1fdf6dfb6b9fd5b01548b4cdd545f9 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 17 Jun 2022 15:54:24 +0200
Subject: [PATCH 1/3] SSS_CLIENT: mem-cache: fixed missing error code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit ffec99930ec84b586f4532246d04be6207396e54)
---
src/sss_client/nss_mc_common.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c
index 8aa8c12c5..dd74b4f2a 100644
--- a/src/sss_client/nss_mc_common.c
+++ b/src/sss_client/nss_mc_common.c
@@ -153,6 +153,7 @@ static errno_t sss_nss_mc_init_ctx(const char *name,
ctx->fd = sss_open_cloexec(file, O_RDONLY, &ret);
if (ctx->fd == -1) {
+ ret = EIO;
goto done;
}
--
2.49.0
From f6a109fad9aa3394fd7f89ac01bb93a2e81d4440 Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Mon, 21 Apr 2025 12:35:58 +0200
Subject: [PATCH 2/3] CLIENT:MC: pointer to context's active_threads shouldn't
be touched
The brief window between saving and restoring the active_threads inside
`sss_nss_mc_destroy_ctx()` can cause a race. Between memset() and
restoring ctx->active_threads, a second thread can enter
`sss_nss_mc_destroy_ctx()`.
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
---
src/sss_client/nss_mc_common.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c
index dd74b4f2a..6ef1f5845 100644
--- a/src/sss_client/nss_mc_common.c
+++ b/src/sss_client/nss_mc_common.c
@@ -116,19 +116,23 @@ errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx)
static void sss_nss_mc_destroy_ctx(struct sss_cli_mc_ctx *ctx)
{
- uint32_t active_threads = ctx->active_threads;
-
if ((ctx->mmap_base != NULL) && (ctx->mmap_size != 0)) {
munmap(ctx->mmap_base, ctx->mmap_size);
}
+ ctx->mmap_base = NULL;
+ ctx->mmap_size = 0;
+
if (ctx->fd != -1) {
close(ctx->fd);
}
- memset(ctx, 0, sizeof(struct sss_cli_mc_ctx));
ctx->fd = -1;
-
- /* restore count of active threads */
- ctx->active_threads = active_threads;
+ ctx->seed = 0;
+ ctx->data_table = NULL;
+ ctx->dt_size = 0;
+ ctx->hash_table = NULL;
+ ctx->ht_size = 0;
+ ctx->initialized = UNINITIALIZED;
+ /* active_threads should be left intact */
}
static errno_t sss_nss_mc_init_ctx(const char *name,
--
2.49.0
From 3175f3b353a2ee356288bdee4e8a56610daebf0d Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Mon, 21 Apr 2025 12:57:51 +0200
Subject: [PATCH 3/3] CLIENT:MC: Validate memory cache before checking header
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
---
src/sss_client/nss_mc_common.c | 39 ++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c
index 6ef1f5845..edde3a20a 100644
--- a/src/sss_client/nss_mc_common.c
+++ b/src/sss_client/nss_mc_common.c
@@ -55,13 +55,40 @@ do { \
} \
} while(0)
+static errno_t sss_nss_mc_validate(struct sss_cli_mc_ctx *ctx)
+{
+ struct stat fdstat;
+
+ __sync_synchronize();
+
+ if (ctx == NULL || ctx->fd < 0) {
+ return EINVAL;
+ }
+
+ if (fstat(ctx->fd, &fdstat) == -1) {
+ return EINVAL;
+ }
+
+ /* Memcache was removed. */
+ if (fdstat.st_nlink == 0) {
+ /* memory cache was removed; we need to reinitialize it. */
+ return EINVAL;
+ }
+
+ return EOK;
+}
+
errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx)
{
struct sss_mc_header h;
bool copy_ok;
int count;
int ret;
- struct stat fdstat;
+
+ ret = sss_nss_mc_validate(ctx);
+ if (ret != EOK) {
+ return ret;
+ }
/* retry barrier protected reading max 5 times then give up */
for (count = 5; count > 0; count--) {
@@ -101,16 +128,6 @@ errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx)
}
}
- ret = fstat(ctx->fd, &fdstat);
- if (ret == -1) {
- return EIO;
- }
-
- if (fdstat.st_nlink == 0) {
- /* memory cache was removed; we need to reinitialize it. */
- return EINVAL;
- }
-
return 0;
}
--
2.49.0