Skip to content

refactor: switch treeland IPC to Qt Remote Objects#96

Open
zccrs wants to merge 1 commit into
linuxdeepin:masterfrom
zccrs:qremoteobject-treeland-ipc
Open

refactor: switch treeland IPC to Qt Remote Objects#96
zccrs wants to merge 1 commit into
linuxdeepin:masterfrom
zccrs:qremoteobject-treeland-ipc

Conversation

@zccrs

@zccrs zccrs commented Jun 2, 2026

Copy link
Copy Markdown
Member

Summary

  • replace the treeland Wayland client IPC in ddm with a Qt Remote Objects replica
  • remove the generated treeland-ddm Wayland client protocol from ddm
  • keep dde-seatd control socket handling unchanged

Testing

  • cmake --build build

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @zccrs, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: zccrs

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch 3 times, most recently from 9c5c73a to 38f5a23 Compare June 3, 2026 02:47
@zccrs zccrs requested a review from Copilot June 3, 2026 02:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors ddm’s Treeland IPC from a generated Wayland client protocol to a Qt Remote Objects (QtRO) replica, aligning the daemon-side connector with Qt’s IPC stack and removing the build-time Wayland-client codegen dependency.

ddm 与 Treeland 的 IPC 进行重构:从原先生成的 Wayland client 协议切换为 Qt Remote Objects(QtRO)replica,使 daemon 侧连接器改用 Qt 的 IPC 机制,并移除构建期的 Wayland-client 协议代码生成依赖。

Changes:

  • Introduces a QtRO replica definition (treelandddmremote.rep) and switches TreelandConnector to call into the generated TreelandDDMRemoteReplica.
  • Removes Wayland client protocol code generation/linkage from CMake and adds Qt6 RemoteObjects dependency.
  • Updates distro/CI dependencies to include Qt Remote Objects (Debian Build-Depends, Arch workflow).

变更点:

  • 新增 QtRO replica 定义(treelandddmremote.rep),并让 TreelandConnector 通过生成的 TreelandDDMRemoteReplica 发起调用。
  • 从 CMake 中移除 Wayland client 协议生成/链接,并新增 Qt6 RemoteObjects 依赖。
  • 更新发行版/CI 依赖(Debian Build-Depends、Arch workflow)以包含 Qt Remote Objects。

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/daemon/treelandddmremote.rep Adds Qt Remote Objects replica interface for Treeland control methods.
src/daemon/TreelandConnector.h Updates connector interface/members for QtRO + local socket usage.
src/daemon/TreelandConnector.cpp Replaces Wayland IPC calls with QtRO replica acquisition and invocation logic.
src/daemon/CMakeLists.txt Hooks qt_add_repc_replicas() and links Qt6::RemoteObjects; removes Wayland-generated source.
CMakeLists.txt Drops Wayland client/TreelandProtocols discovery; adds Qt6 RemoteObjects requirement.
debian/control Adds qt6-remoteobjects-dev to Build-Depends.
.github/workflows/ddm-archlinux-build.yml Installs Qt Remote Objects dependency for Arch CI build.
Comments suppressed due to low confidence (1)

src/daemon/TreelandConnector.h:43

  • Include guards need to be closed at the end of the header (#endif).

建议:在文件末尾补上 #endif,与文件开头的 #ifndef/#define 成对。

};
}

Comment thread src/daemon/TreelandConnector.cpp Outdated
Comment thread src/daemon/TreelandConnector.cpp Outdated
Comment thread src/daemon/TreelandConnector.cpp Outdated
Comment thread src/daemon/TreelandConnector.h Outdated
Comment thread src/daemon/TreelandConnector.h Outdated
Comment thread .github/workflows/ddm-archlinux-build.yml Outdated
Comment thread debian/control Outdated
Comment thread src/daemon/TreelandConnector.cpp Outdated
Comment thread src/daemon/treelandddmremote.rep Outdated
Comment thread src/daemon/treelandddmremote.rep Outdated
@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch from 38f5a23 to d13b4bb Compare June 3, 2026 04:04
@zccrs

zccrs commented Jun 3, 2026

Copy link
Copy Markdown
Member Author

已按这轮 review 收口:

  • TreelandConnector 里重复实现的 dde-seatd control socket / grouped-VT 逻辑已全部删除,VT 事件统一回到现有 DdeSeatdControl + SeatManager::handleVtChanged()
  • treelandddmremote.rep 已删掉未再使用的 activateSession/deactivateSession/enableRender/disableRender,两端接口只保留当前实际使用的 switchToGreeter/switchToUser
  • TreelandConnector.h 已改为 #pragma once,空的 setSignalHandler() 和未使用的 grouped-VT 包装接口一并移除。
  • debian/control、Arch/Deepin CI 中残留的 libwayland-dev / treeland-protocols 构建依赖已删除;本分支当前已不再使用这些构建输入。

之前 Copilot 提到的同步 control-socket I/O、协议版本、getpwnam()、TOCTOU 等问题,都是基于那套已经删掉的重复实现,当前 head 已不再适用。#endif 那条也是误报:这里现在用的是 #pragma once

@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch from d13b4bb to 40ceee2 Compare June 3, 2026 10:36
Comment thread src/daemon/TreelandConnector.cpp Outdated
Comment thread src/daemon/TreelandConnector.cpp Outdated
Comment thread src/daemon/SocketServer.cpp Outdated
Comment thread src/daemon/SocketServer.cpp Outdated
Comment thread src/daemon/greeterddmremote.rep Outdated
Comment thread src/daemon/SocketServer.cpp Outdated
@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch 7 times, most recently from f308bc0 to 1ca093d Compare June 4, 2026 08:37
@deepin-bot

deepin-bot Bot commented Jun 4, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.3.5
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #100

Comment thread src/daemon/Display.cpp Outdated
Comment thread src/daemon/Display.cpp Outdated
Comment thread src/daemon/Display.cpp
Comment thread src/daemon/SocketServer.cpp Outdated
Comment thread src/daemon/SocketServer.cpp Outdated
Comment thread src/daemon/SocketServer.cpp
Comment thread src/daemon/SocketServer.cpp Outdated
@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch 6 times, most recently from 63e12e6 to 94014e1 Compare June 8, 2026 03:44
@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch 13 times, most recently from bdba11d to ad94775 Compare June 12, 2026 03:21
@deepin-bot

deepin-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.3.6
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #102

@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch 3 times, most recently from 767f071 to 56ffbd0 Compare June 16, 2026 13:00
Publish session list and remembered user/session state from DDMRemote.

Serve DDMRemote directly on local:org.deepin.dde.ddm.qro.

Log: 通过 QtRO 向 Treeland 暴露完整 greeter 状态

Influence: Treeland 不再需要链接 libddm 即可获取 greeter 所需数据。
@zccrs zccrs force-pushed the qremoteobject-treeland-ipc branch from 56ffbd0 to 46ec0a3 Compare June 16, 2026 13:14
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:20分

■ 【总体评价】

代码成功将底层IPC通信从自定义Socket协议重构为Qt6 RemoteObjects RPC机制,但引入了严重的本地套接字权限缺失漏洞
逻辑正确但因丢失关键的安全权限配置导致任意本地用户可接管显示管理器,强制触发安全上限扣分

■ 【详细分析】

  • 1.语法逻辑(基本正确)✓

重构后的代码使用了现代C++特性如std::unique_ptrQPointer来管理生命周期,Display::watchUserSession中通过QPointer有效防止了异步回调中的悬空指针解引用,unwatchUserSession通过对象名称精准清理关联的DBus代理,整体无编译错误或内存泄漏风险
建议:无

  • 2.代码质量(良好)✓

移除了大量基于QDataStream的手动序列化与反序列化样板代码,改用声明式的.rep接口定义文件,大幅降低了协议解析的复杂度;PowerManager中将位掩码运算拆分为独立的canXxx()虚函数,消除了原先重复的DBus调用和位运算逻辑,符合单一职责原则
建议:无

  • 3.代码性能(存在性能问题)✕

TreelandConnector::ensureRemote函数中,调用了m_remoteReplica->waitForSource(3000),该方法是同步阻塞的。由于ensureRemote最终由RPC槽函数SocketServer::connectGreeter触发,而QRemoteObjectHost默认在主线程的事件循环中处理连接,这将导致DDM主线程在Treeland未就绪时阻塞最多3秒,造成系统启动或切换会话时的明显卡顿
建议:将同步的waitForSource替换为基于QRemoteObjectReplica::stateChanged信号的异步状态机,或使用QEventLoop配合超时在非关键路径上进行有限等待

  • 4.代码安全(存在 2 个安全漏洞(严重1个,低危1个))✕

漏洞对比统计:新增漏洞 2 个,减少漏洞 0 个,持平 0 个
总体风险描述:重构过程中丢失了原有的本地套接字访问控制,导致DDM的核心控制接口暴露给系统上的所有普通用户,可被利用进行拒绝服务或本地提权

  • 安全漏洞1(严重):本地权限提升与拒绝服务 在 SocketServer::start 中,使用QRemoteObjectHost替代了原有的QLocalServer,但彻底丢失了原代码中m_server->setSocketOptions(QLocalServer::UserAccessOption)的关键安全配置。QRemoteObjectHost底层创建的Unix Domain Socket默认权限过于宽松,允许系统上任意用户连接。攻击者可通过连接local:org.deepin.dde.ddm.qro套接字,直接调用login接口进行离线密码爆破,或调用powerOffreboot等接口导致系统立即关机,实现本地权限提升与拒绝服务攻击 ——非常重要

  • 安全漏洞2(低危):锁屏防抖逻辑可被物理绕过 在 Display::watchUserSessionUnlock信号处理中,设置了2秒内最多回弹锁定3次的防抖阈值。若攻击者通过快速注入内核输入事件或定制硬件触发logind的Unlock信号超过3次,该防抖机制将失效并停止回弹,可能导致logind与Treeland之间的锁屏状态不一致 ——非常重要

  • 建议:针对漏洞1,必须在QRemoteObjectHost启动后立即通过chmod系统调用将生成的套接字文件权限强制修改为0600;针对漏洞2,建议在达到防抖阈值时不仅停止回弹,还应记录安全审计日志并触发系统级警报

■ 【改进建议代码示例】

#include <sys/stat.h>
#include <errno.h>
#include <string.h>

bool SocketServer::start() {
    if (m_host)
        return false;

    qDebug() << "Socket server starting...";

    m_host = new QRemoteObjectHost(QUrl(QString::fromLatin1(ddmRemoteUrl)), this);
    if (!m_host->enableRemoting(this, QString::fromLatin1(ddmRemoteSourceName))) {
        qCritical() << "Failed to enable DDMRemote source.";
        delete m_host;
        m_host = nullptr;
        return false;
    }

    // Security Fix: QRemoteObjectHost does not expose QLocalServer::UserAccessOption.
    // We must manually restrict the socket file permissions to prevent local unauthorized access.
    QString socketPath = QString::fromLatin1(ddmRemoteUrl);
    if (socketPath.startsWith(QStringLiteral("local:"))) {
        socketPath.remove(QStringLiteral("local:"));
        QFile socketFile(socketPath);
        if (socketFile.exists()) {
            if (chmod(qPrintable(socketPath), 0600) != 0) {
                qCritical() << "CRITICAL SECURITY: Failed to set secure permissions on DDM socket:"
                            << socketPath << "Error:" << strerror(errno);
                // Fallback to safe state: abort starting if we cannot secure the socket
                m_host->deleteLater();
                m_host = nullptr;
                return false;
            }
            qDebug() << "Successfully secured DDM socket permissions to 0600:" << socketPath;
        } else {
            qWarning() << "Socket file not found immediately after start, attempting fallback wait:" << socketPath;
            // Wait briefly for the file system to sync
            for (int i = 0; i < 5; ++i) {
                QThread::usleep(10000);
                if (socketFile.exists()) {
                    if (chmod(qPrintable(socketPath), 0600) != 0) {
                        qCritical() << "CRITICAL SECURITY: Failed to set secure permissions on DDM socket:"
                                    << socketPath << "Error:" << strerror(errno);
                        m_host->deleteLater();
                        m_host = nullptr;
                        return false;
                    }
                    qDebug() << "Successfully secured DDM socket permissions to 0600 on retry:" << socketPath;
                    break;
                }
            }
        }
    }

    setHostName(daemonApp->hostName());
    qDebug() << "Socket server started on" << ddmRemoteUrl;
    return true;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants