From e7d3065cf47c9d8430be409a0c53422aea2e3532 Mon Sep 17 00:00:00 2001 From: zousar Date: Mon, 13 Apr 2026 14:08:09 -0600 Subject: Stop using O_CLOEXEC in shm_open --- src/zencore/filesystem.cpp | 3 ++- src/zenutil/zenserverprocess.cpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp index 70d0f32b3..debe51cc9 100644 --- a/src/zencore/filesystem.cpp +++ b/src/zencore/filesystem.cpp @@ -3462,11 +3462,12 @@ public: ZEN_UNUSED(SystemGlobal); std::string InstanceMapName = fmt::format("/{}", Name); - ScopedFd FdGuard(shm_open(InstanceMapName.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0666)); + ScopedFd FdGuard(shm_open(InstanceMapName.c_str(), O_RDWR | O_CREAT, 0666)); if (!FdGuard) { return {}; } + fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); fchmod(FdGuard.Fd, 0666); int Result = ftruncate(FdGuard.Fd, Size); diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index 9a282a848..20208e136 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -181,7 +181,7 @@ ZenServerState::Initialize() ThrowLastError("Could not map view of Zen server state"); } #else - int Fd = shm_open("/UnrealEngineZen", O_RDWR | O_CREAT | O_CLOEXEC, geteuid() == 0 ? 0766 : 0666); + int Fd = shm_open("/UnrealEngineZen", O_RDWR | O_CREAT, geteuid() == 0 ? 0766 : 0666); if (Fd < 0) { // Work around a potential issue if the service user is changed in certain configurations. @@ -191,12 +191,13 @@ ZenServerState::Initialize() // shared memory object and retry, we'll be able to get past shm_open() so long as we have // the appropriate permissions to create the shared memory object. shm_unlink("/UnrealEngineZen"); - Fd = shm_open("/UnrealEngineZen", O_RDWR | O_CREAT | O_CLOEXEC, geteuid() == 0 ? 0766 : 0666); + Fd = shm_open("/UnrealEngineZen", O_RDWR | O_CREAT, geteuid() == 0 ? 0766 : 0666); if (Fd < 0) { ThrowLastError("Could not open a shared memory object"); } } + fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); fchmod(Fd, 0666); void* hMap = (void*)intptr_t(Fd); @@ -244,11 +245,12 @@ ZenServerState::InitializeReadOnly() ThrowLastError("Could not map view of Zen server state"); } #else - int Fd = shm_open("/UnrealEngineZen", O_RDONLY | O_CLOEXEC, 0666); + int Fd = shm_open("/UnrealEngineZen", O_RDONLY, 0666); if (Fd < 0) { return false; } + fcntl(Fd, F_SETFD, FD_CLOEXEC); void* hMap = (void*)intptr_t(Fd); void* pBuf = mmap(nullptr, MapSize, PROT_READ, MAP_SHARED, Fd, 0); @@ -651,11 +653,12 @@ ZenServerInstanceInfo::Create(const Oid& SessionId, const InstanceInfoData& Data ThrowLastError("Could not map instance info shared memory"); } #else - int Fd = shm_open(Name.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666); + int Fd = shm_open(Name.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); if (Fd < 0) { ThrowLastError("Could not create instance info shared memory"); } + fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); fchmod(Fd, 0666); if (ftruncate(Fd, kInstanceInfoSize) < 0) @@ -718,11 +721,12 @@ ZenServerInstanceInfo::OpenReadOnly(const Oid& SessionId) return false; } #else - int Fd = shm_open(Name.c_str(), O_RDONLY | O_CLOEXEC, 0666); + int Fd = shm_open(Name.c_str(), O_RDONLY, 0666); if (Fd < 0) { return false; } + fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); void* pBuf = mmap(nullptr, kInstanceInfoSize, PROT_READ, MAP_SHARED, Fd, 0); if (pBuf == MAP_FAILED) -- cgit v1.2.3 From f2eb4ff5ec5446b4d01d67e89976728d88be598e Mon Sep 17 00:00:00 2001 From: zousar Date: Mon, 13 Apr 2026 14:24:11 -0600 Subject: Fix copy and paste errors --- src/zenutil/zenserverprocess.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index 20208e136..25e9cfa5d 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -197,7 +197,7 @@ ZenServerState::Initialize() ThrowLastError("Could not open a shared memory object"); } } - fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); + fcntl(Fd, F_SETFD, FD_CLOEXEC); fchmod(Fd, 0666); void* hMap = (void*)intptr_t(Fd); @@ -658,7 +658,7 @@ ZenServerInstanceInfo::Create(const Oid& SessionId, const InstanceInfoData& Data { ThrowLastError("Could not create instance info shared memory"); } - fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); + fcntl(Fd, F_SETFD, FD_CLOEXEC); fchmod(Fd, 0666); if (ftruncate(Fd, kInstanceInfoSize) < 0) @@ -726,7 +726,7 @@ ZenServerInstanceInfo::OpenReadOnly(const Oid& SessionId) { return false; } - fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); + fcntl(Fd, F_SETFD, FD_CLOEXEC); void* pBuf = mmap(nullptr, kInstanceInfoSize, PROT_READ, MAP_SHARED, Fd, 0); if (pBuf == MAP_FAILED) -- cgit v1.2.3 From 0c0dc044614e5f91b908d131148eabc393bb60a9 Mon Sep 17 00:00:00 2001 From: zousar Date: Mon, 13 Apr 2026 14:24:19 -0600 Subject: Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0f7a79c3..aa35ca96c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ - Improvement: Default memory allocator changed back to mimalloc from rpmalloc - Bugfix: Dashboard stats tiles no longer flicker on page load when WebSocket updates arrive before all stats are available - Bugfix: Build storage operations now silence HTTP exceptions on aborted requests instead of logging spurious errors +- Bugfix: Avoid use of `O_CLOEXEC` when operating on shared memory on Mac and Linux as it was reported to cause issues for MacOS 26.4 and later ## 5.8.3 - Feature: Incremental CAS-based hydration/dehydration replacing the previous full-copy approach -- cgit v1.2.3 From ecd4acb89406cfa573d1819532dcaec2c44113f5 Mon Sep 17 00:00:00 2001 From: zousar Date: Mon, 13 Apr 2026 14:42:13 -0600 Subject: Removing CLOEXEC use on shared memory descriptors According to documentation, shm_open already sets O_CLOEXEC. --- src/zencore/filesystem.cpp | 1 - src/zenutil/zenserverprocess.cpp | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp index debe51cc9..5160bfdc6 100644 --- a/src/zencore/filesystem.cpp +++ b/src/zencore/filesystem.cpp @@ -3467,7 +3467,6 @@ public: { return {}; } - fcntl(FdGuard.Fd, F_SETFD, FD_CLOEXEC); fchmod(FdGuard.Fd, 0666); int Result = ftruncate(FdGuard.Fd, Size); diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index 25e9cfa5d..1fe373228 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -197,7 +197,6 @@ ZenServerState::Initialize() ThrowLastError("Could not open a shared memory object"); } } - fcntl(Fd, F_SETFD, FD_CLOEXEC); fchmod(Fd, 0666); void* hMap = (void*)intptr_t(Fd); @@ -250,7 +249,6 @@ ZenServerState::InitializeReadOnly() { return false; } - fcntl(Fd, F_SETFD, FD_CLOEXEC); void* hMap = (void*)intptr_t(Fd); void* pBuf = mmap(nullptr, MapSize, PROT_READ, MAP_SHARED, Fd, 0); @@ -658,7 +656,6 @@ ZenServerInstanceInfo::Create(const Oid& SessionId, const InstanceInfoData& Data { ThrowLastError("Could not create instance info shared memory"); } - fcntl(Fd, F_SETFD, FD_CLOEXEC); fchmod(Fd, 0666); if (ftruncate(Fd, kInstanceInfoSize) < 0) @@ -726,7 +723,6 @@ ZenServerInstanceInfo::OpenReadOnly(const Oid& SessionId) { return false; } - fcntl(Fd, F_SETFD, FD_CLOEXEC); void* pBuf = mmap(nullptr, kInstanceInfoSize, PROT_READ, MAP_SHARED, Fd, 0); if (pBuf == MAP_FAILED) -- cgit v1.2.3