From 9501ea34d850d66d2e51f1a964f4611d263bc8f2 Mon Sep 17 00:00:00 2001 From: zorowk Date: Tue, 14 Jul 2026 15:53:37 +0800 Subject: [PATCH] fix(auth): release daemon descriptors in session child MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close inherited daemon file descriptors in the forked session leader so old D-Bus connections cannot retain the display manager service names. Fail fast when D-Bus registration is unavailable and restore the original service start limit. Log: DDM 通过 fork 创建 session leader 时,子进程若继承 system D-Bus fd,旧 DDM 主进程退出后仍可能保留 org.deepin.DisplayManager 服务名,阻 止新 DDM 注册。session child 仅保留标准流和与父进程通信的 pipe,并关闭 其余 daemon fd;DDM 注册 D-Bus 服务或对象失败时立即退出,避免 systemd 显示 active 而 D-Bus 实际不可用。该修复不处理 systemd start-limit-hit; DDM 被限流停止时必须 reset-failed 后重新启动。 PMS: Influence: Affects session startup and DDM D-Bus ownership across daemon restarts. --- src/daemon/Auth.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/daemon/Auth.cpp b/src/daemon/Auth.cpp index c55e24e..ecb482b 100644 --- a/src/daemon/Auth.cpp +++ b/src/daemon/Auth.cpp @@ -17,11 +17,53 @@ #include #include #include +#include +#include #include #include namespace DDM { +#ifdef SYS_close_range + bool tryCloseInheritedWithCloseRange(int preservedFd) + { + const unsigned int first = STDERR_FILENO + 1; + const unsigned int last = UINT_MAX; + + // No preserved FD in range: just close everything + if (preservedFd < 0 || static_cast(preservedFd) < first) + return syscall(SYS_close_range, first, last, 0) == 0; + + const unsigned int uPreservedFd = static_cast(preservedFd); + + // Close [first, preservedFd - 1] + if (uPreservedFd > first) { + if (syscall(SYS_close_range, first, uPreservedFd - 1, 0) == -1) + return false; + } + + // Close [preservedFd + 1, last] + if (uPreservedFd < last) { + if (syscall(SYS_close_range, uPreservedFd + 1, last, 0) == -1) + return false; + } + return true; + } +#endif + + void closeInheritedFileDescriptors(int preservedFd) + { +#ifdef SYS_close_range + if (tryCloseInheritedWithCloseRange(preservedFd)) + return; +#endif + const long maxFd = sysconf(_SC_OPEN_MAX); + for (int fd = STDERR_FILENO + 1; fd < maxFd; ++fd) { + if (fd != preservedFd) + close(fd); + } + } + /////////////////////////// // utmp helper functions // /////////////////////////// @@ -255,6 +297,10 @@ namespace DDM { // Delete old signal handlers, in order to close old fds // which are shared with the parent process. delete daemonApp->signalHandler(); + // The session leader must not keep daemon-owned sockets alive. + // In particular, an inherited system bus fd would retain DDM's + // well-known names after the daemon exits. + closeInheritedFileDescriptors(pipefd[1]); // Restore default SIGINT and SIGTERM handlers. We need // the signal hander to terminate ourself, since we're