目录

1) 引言

Deepin 桌面环境(DDE)是 Deepin Linux 发行版的一部分。它注重可用性、精美的图形界面和对中文的支持。它也可用于许多其他 Linux 发行版,包括 openSUSE。

最近,我们注意到 openSUSE 中 Deepin 桌面环境的打包存在策略违规行为。为了规避安全审查要求,我们的 Deepin 社区打包者实施了一种变通方法,绕过了常规的 RPM 打包机制来安装受限制的资产。

由于这次违规以及我们与 Deepin 代码审查之间长期存在的困难,我们将暂时从 openSUSE 发行版中移除 Deepin 桌面环境的软件包。

在本博文中,我们将探讨此次策略违规的具体性质,Deepin 组件在 openSUSE 中的审查历史,以及我们从中得出的结论。最后,我们将展望如何解决这一局面,以及 openSUSE 用户未来如何继续选择使用 Deepin。

2)通过“许可协议”对话框绕过 openSUSE 打包策略

SUSE 安全团队对 openSUSE 发行版强制执行一系列打包限制。其中包括,D-Bus 系统服务配置文件和 Polkit 策略的安装需要我们进行审查。当我们对软件包的安全性满意后,我们会为其添加白名单。之后,该软件包就可以提交到 Open Build Service 中的 openSUSE:Factory 项目,这是 openSUSE Tumbleweed 滚动发布发行版的基础。

对于像 Deepin 这样包含大量 D-Bus 服务的庞大软件套件来说,这可能是一个难以克服的初期障碍。自 2017 年以来,我们一直与 openSUSE Deepin 打包者保持联系,并已为各种 Deepin D-Bus 组件添加了白名单。然而,近年来,许多剩余的 Deepin 审查错误进展缓慢,因为我们指出的问题并未得到妥善解决。

打包者可能因为厌倦等待,决定尝试另一种方式来将剩余的 Deepin 组件引入 openSUSE,从而绕过审查要求。2025 年 1 月,在例行审查期间,我们偶然发现了 deepin-feature-enable 软件包,该软件包于 2021-04-27 引入,但未咨询或告知我们。这个名称无害的软件包实现了一个“许可协议对话框”,该对话框基本上解释了 SUSE 安全团队对 Deepin 安全性表示怀疑,但要正常使用 Deepin,某些组件仍需要安装。因此,如果用户不关心安全性,“许可”应被接受。如果用户接受,缺少 D-Bus 配置文件和 Polkit 策略将从 deepin-daemon-dbusdeepin-daemon-polkit 软件包中的 tarball 中自动提取到系统目录中。许可文本还包含一个提示,建议手动安装 deepin-file-manager-dbusdeepin-file-manager-polkit 软件包,并运行一个脚本来侧载 Deepin 文件管理器 D-Bus 组件正常工作所需的其他配置文件。

The 'license agreement' dialog presented by deepin-feature-enable
deepin-feature-enable 呈现的“许可协议”对话框。

对于终端用户来说,这意味着在安装 Deepin 模式时输入一次“y”即可选择激活 SUSE 安全团队未批准的、安全性可疑的组件。

考虑到多年来的审查数量,以及频率和活动度的下降,我们错误地认为,除了某些可选的实用程序包外,大部分 Deepin D-Bus 组件应该已经通过了我们的白名单并进入了 openSUSE:Factory。然而,我们却发现核心组件(存在于 deepin-daemon 软件包中)从未提交给我们审查,而是被偷偷塞进了 openSUSE。

自 2019 年以来,Deepin 文件管理器的审查错误一直在运行,但软件包一直未达到令人满意的状态。提供给用户运行脚本来激活有问题的组件的能力,比通过精心设计的“许可对话框”自动执行此操作的风险要小,但仍然是一种不干净且有问题的做法。

3)Deepin 组件审查历史

本节概述了 Deepin 组件在 openSUSE 中审查请求的悠久历史。这应该能让我们了解在检查 Deepin 的安全性方面已经付出的努力,以及我们在努力达成良好解决方案时经常遇到的困难。

2017-12-04:deepin-api:D-Bus 服务和 Polkit 操作的初步审查

这是我们收到的第一个关于 Deepin 的审查请求。当时我们的团队正在进行重组,导致我们在找到时间处理它之前延迟了大约半年。 deepin-api 包含一个以 root 身份运行的 D-Bus 服务,在 D-Bus 系统总线上提供各种杂项 D-Bus 方法,例如播放音频文件。

我们在 D-Bus 方法实现中发现了各种问题。最重要的是,系统中的任何用户都被允许以 root 身份运行各种命令,如 rfkill,并带任意参数。Polkit 身份验证仅在部分 D-Bus 方法中实现,而其他方法则只有一个 TODO: 标记来添加身份验证。此外,为某些方法实现的 Polkit 身份验证存在竞态条件,可能导致身份验证绕过。

Deepin 打包者与上游联系,我们开始在审查错误中讨论如何解决这些问题。第一次尝试修复它们,结果并不完整。我们要求 Deepin 项目提供正式的安全联系人以便协调披露,因为我们同时在其他 Deepin 组件中也发现了问题。尽管如此,我们没有收到任何答复。

在最初的活动之后,六个月没有任何进展,因此我们在 2019 年 12 月因不活跃而关闭了此错误。2021 年 4 月,Deepin 打包者重新打开了此错误,并将其分配给了一位上游开发人员。2021 年 7 月,我们最终获得了正确的修复方案,并在 2021 年 8 月为此特定的 Deepin 组件授予了白名单。

2019-03-25:deepin-clone:Polkit 操作 com.deepin.pkexec.deepin-clone

deepin-clone 是 Deepin 桌面的备份工具。2019 年 3 月,我们收到了该软件包中包含的 Polkit 操作的审查请求。我们在该 Polkit 操作的实现中发现了大量问题,例如在 /tmp 中使用有问题的可预测文件,在 /tmp 中存在一个固定路径的全局可读日志文件,以及阻止临时挂载的块设备卸载的可能性。

我们在 2019 年 4 月向打包者报告了这些问题。2019 年 7 月,我们获得了一些修复方案,但我们发现其中一些问题仍未得到解决,代码总体上看起来仍然不干净。至少最严重的问题得到了修复,因此我们为其请求了 CVE,并在 oss-security 邮件列表中发布了一份报告

我们从未收到关于我们仍存在的担忧的回复,因此从未授予此组件的白名单。

2019-05-05:deepin-file-manager:D-Bus 服务和 Polkit 操作

2019 年 5 月,我们收到了 deepin-file-manager 软件包的D-Bus 部分Polkit 部分的审查请求。此应用程序是一个文件管理器,类似于 KDE 中的 Dolphin 或 GNOME 中的 Nautilus。软件包中实现的 D-Bus 服务提供了执行诸如挂载 Samba 网络共享或管理系统中用户账户的 UNIX 组成员资格等操作的方法。这是 Deepin 打包者最终实现了白名单绕过的软件包之一,如第 2 节中所述。

在审查了主要的 D-Bus 服务后,我们不得不称之为安全噩梦。该服务的方法不仅未经身份验证,因此系统中的所有用户都可以访问,而且 D-Bus 配置文件还允许任何人拥有系统总线上的 D-Bus 服务路径,这可能导致伪装守护进程。除其他问题外,D-Bus 服务允许系统中的任何人创建任意新的 UNIX 组,将任意用户添加到任意组,设置任意用户的 Samba 密码,或通过以 root 身份调用 mkfs 来覆盖系统上几乎任何文件,从而导致数据丢失和拒绝服务。该守护进程确实包含一些 Polkit 身份验证代码,但它们都位于未使用的代码路径中;此外,该代码以不安全的方式使用已弃用的 UnixProcess Polkit 主题,如果使用的话,这将使其容易受到竞态条件的攻击,从而允许身份验证绕过。

软件包中发现的其他 Polkit 策略至少还在使用。一个 Polkit 操作允许本地登录用户以 root 身份无验证地运行 /usr/bin/usb-device-formatter。该程序允许确定系统中任意文件的存在,并卸载或格式化非忙的文件系统。一位 Deepin 开发人员加入了错误讨论,我们再次试图将 Deepin 的整体安全状况引起上游注意,但徒劳无功。

出现了一些针对 Polkit 问题的错误修复,但再次不完整。到 2019 年 12 月,我们没有收到任何进一步的回复,因此我们在未为 Polkit 策略添加白名单的情况下关闭了此错误。2021 年 3 月,Deepin 打包者重新打开了此错误,但直到 2022 年 10 月才向我们指出所谓的修复。此时,我们将 Polkit 部分的讨论转移到了 D-Bus 服务组件的其他错误中。

对于 D-Bus 服务问题,我们未收到任何回复,因此也在 2019 年 12 月关闭了此错误,未为该服务添加白名单。与此同时,我们在 2019 年 8 月在 oss-security 邮件列表中发布了我们的发现。2021 年 4 月,Deepin 打包者重新打开了此错误,称上游将处理这些问题。2021 年 8 月,一位上游开发人员被分配到此错误,他指出了一个部分修复,但同时表示 Deepin 开发人员对报告的安全问题“有不同的看法”,但没有提供进一步的细节。

2022 年 10 月,Deepin 打包者向我们指出了更多修复和为 openSUSE 打包的新版本。此时,D-Bus 接口得到了重大更改。现在已为一些 D-Bus 调用添加了 Polkit 身份验证,但它再次以不安全的方式使用了已弃用的 UnixProcess 主题,这可能会通过竞态条件绕过身份验证。新添加的 D-Bus 方法也引入了新问题,例如在卸载 Samba 共享时缺少路径验证。另一些方法仍然完全未经验证。

2023 年 11 月,Deepin 打包者通知我们又发布了一个新版本,其中包含更多错误修复。这次,一些有问题的 D-Bus 方法完全消失了,但一些原始问题以及令人困惑和有缺陷的 Polkit 身份验证尝试仍然存在。

2024 年 4 月,Deepin 打包者再次通知我们发布了一个包含错误修复的新版本。一些 D-Bus 方法再次被简单地删除,一些现在实际上使用了基于 D-Bus 系统总线名称的正确 Polkit 身份验证。但是,D-Bus 服务配置仍然允许系统中的任何用户伪装服务。此外,又有一堆新添加的 D-Bus 方法引入了新问题。例如,其中一个允许系统中的任何用户启动 Samba 系统守护进程 nmbdsmbd。许多路径验证问题也依然存在于新的 API 中。

我们没有收到关于这些审查的进一步回复,组件仍未获得 openSUSE 的白名单。由于 Deepin 文件管理器守护进程中的 D-Bus 方法频繁更改,导致部分错误修复和新问题出现,我们也避免为这些问题分配更多的 CVE。形式上,每一次不完整的错误修复都需要一个专门的 CVE,这将导致一份令人困惑的冗长 CVE 列表,围绕同一主题:Deepin 文件管理器守护进程存在严重安全问题,其中一些可能仍未修复。

2019-05-23:deepin-anything:D-Bus 服务

2019 年 5 月,我们收到了 deepin-anything 软件包的审查请求。此组件充当桌面搜索引擎的后端。考虑到当时我们已经面临大量未解决的 Deepin 相关审查,我们拒绝在其他问题解决之前处理此附加审查。

尽管如此,仅仅从快速浏览软件包,我们就注意到了另一个问题:D-Bus 服务配置允许系统中的任何用户在系统总线上注册 deepin-anything 服务。

2024 年 9 月,Deepin 打包者再次联系我们,指出了上游 D-Bus 配置的更改。我们那时没有再仔细查看,因为当时我们对 Deepin 的优先级较低。

2021-02-01:dtkcommon:FileDrag D-Bus 服务

2021 年 2 月,又来了一个审查请求。这次是关于一个“com.deepin.dtk.FileDrag”D-Bus 接口,但该 D-Bus 服务的实际实现仍然是一个谜。最终,上游在 2021 年 7 月将此接口移至 D-Bus 会话总线,因此我们不再需要白名单。

有趣的是,Deepin 打包者在错误中提到,上游发现自己无法响应安全错误报告,这对于一个拥有大量未暴露安全问题的大型项目来说,是相当令人担忧的。

2021-02-06:deepin-system-monitor:Polkit 策略

这个请求也于 2021 年 2 月提交。它是少数几个完成得相当快且没有重大担忧的 Deepin 审查之一。Polkit 策略只允许通过 pkexec 工具执行诸如 killrenicesystemctl 等程序。这仅在管理员身份验证后才允许。我们在 2021 年 5 月为其添加了白名单。

2023-05-13:deepin-app-services:dde-dconfig-daemon D-Bus 服务

这里我们看到了自上次 Deepin 审查请求以来的大约两年空白期。这可能是因为在此期间引入了违规的 deepin-feature-enable 软件包(于 2021 年 5 月引入)来规避白名单要求。然而,打包者似乎仍然愿意让我们审查包含 D-Bus 组件的新 Deepin 软件包。

不幸的是,对 deepin-app-services审查是另一个混乱的案例,而且至今仍未完成。即使理解这个 D-Bus 服务的目的也很困难,因为组件并没有真正设计文档或目的描述。通过查看 D-Bus 服务实现,我们判断它是一种用于 Deepin 的系统范围配置存储。与其他大多数 Deepin D-Bus 服务不同,它不是以 root 身份运行,而是以一个专门的非特权服务用户身份运行。

我们很快在这个 D-Bus 服务中发现了一类问题,即通过在用于查找配置文件的一些 D-Bus 输入参数中添加 ../ 组件来构造相对路径名。似乎 D-Bus 服务应该只允许从 /usr 中的受信任路径查找 JSON 配置文件。然而,通过构造相对路径,可以欺骗 D-Bus 服务加载来自任意位置的不可信 JSON 配置。鉴于配置存储的抽象性质,我们不完全确定其影响,但它似乎具有安全相关性,因为上游对我们报告的此问题做出了反应。

然而,上游经过了三次迭代和一年的时间,才修复了所有允许构造任意路径的输入参数组合。上游并未自行验证和解决这些问题。相反,他们只修复了我们报告的具体问题,当我们回到审查时,又发现了更多绕过 /usr 路径限制的方法。

2024 年 12 月,我们接近为这个 D-Bus 服务添加白名单。然而,经过这么长时间的推移,我们认为最好重新审视 D-Bus 接口的当前情况。这导致了一系列新担忧,部分原因在于路径查找,也因为任意用户可以读取和存储任意其他用户的配置。该接口缺乏 Polkit 身份验证和用户隔离。

2023-05-13:deepin-api:D-Bus 和 Polkit 的后续审查

与上一节描述的 deepin-app-services 审查并行,我们还收到了 deepin-api后续审查请求。这次审查的触发因素是上游将他们的 D-Bus 接口和 Polkit 操作名称从 com.deepin.* 重命名为 org.deepin.*

幸运的是,这次 D-Bus 服务的实现与上次相比变化不大,我们也未能发现任何新的安全问题。因此,我们迅速接受了更改并完成了审查。

2024-08-29:deepin-api-proxy:D-Bus 服务

在 Deepin 审查长时间停滞后,又来了一个关于添加 deepin-api-proxy请求。这个软件包迎面而来的是二十多个 D-Bus 配置文件。同样,上游对该组件功能描述非常简略。通过查看实现,我们推断此代理组件似乎与上一节所述的接口重命名有关。

我们在代理的设计中发现了一个设计缺陷,该缺陷允许本地 root 漏洞。你可以在我们不久前发布的专门博文中找到详细信息。

值得注意的是,在我们开始为此发现启动的协调披露过程中,与上游的沟通被证明非常困难。我们没有及时收到回复,这几乎导致我们单方面发布报告,直到上游在最后一刻终于表达了他们希望遵循协调披露的意愿。我们没有收到上游修复程序发布的通知,也没有与我们分享或讨论过该错误修复。这导致了一个后续安全问题,因为上游再次依靠已弃用的 Polkit UnixProcess 主题的不安全使用来进行身份验证。

对该组件的审查也让我们发现了通过 deepin-feature-enable 软件包绕过安全白名单的行为,因为我们多年来第一次安装了完整的 Deepin 桌面环境,这触发了上面描述的“许可协议”对话框。了解这一点后,我们决定根据我们长期的经验,重新评估 Deepin 在 openSUSE 中的整体问题。

2024-09-02:deepin-system-monitor:添加了 D-Bus 服务和新的 Polkit 操作

deepin-system-monitor 收到了新的 D-Bus 服务额外的 Polkit 操作的添加。我们接受了 D-Bus 服务,尽管它包含一些怪癖。然而,直到现在我们还没有时间完全完成 Polkit 操作的审查。对 D-Bus 服务进行第二次查看发现,它再次以不安全的方式使用了已弃用的 UnixProcess 主题进行 Polkit 身份验证。这是我们之前疏忽的地方。

4)关于 Deepin 在 openSUSE 未来发展的结论

我们与 Deepin 软件及其上游在代码审查方面的经验并不理想。我们报告的安全问题不止一次被新的安全问题取代。另一些时候,上游没有投入精力来充分分析我们报告的问题,并且修复不充分。一般来说,与上游的沟通被证明很困难,也许也因为语言障碍。尽管上游有时表示他们没有足够的资源来处理安全报告,这本身就足够令人担忧了,但 Deepin D-Bus 组件的设计和实现却常常以无关的方式发生根本性变化。这使得 Deepin 组件的安全评估成为一个不断变化的目标。因此,多年来建立对 Deepin 组件的信任一直极其困难。

Deepin 代码审查的历史清楚地表明,上游缺乏安全文化,并且同类别的安全问题不断出现。尽管我们只审查了 Deepin 代码的一小部分,但每次审查其组件时,我们几乎都发现了安全问题。基于这些经验,我们预计其余未引起注意的 Deepin 代码中还会存在进一步的安全问题,因为 D-Bus 服务(由于它们以提升的权限运行)会引起注意。鉴于我们在 Deepin D-Bus 服务方面的经验,我们认为它们很可能会破坏用户隔离。这些组件肯定不适合多用户系统;即使在单用户系统上,它们也会显著削弱纵深防御。

通过 deepin-feature-enable 软件包绕过安全白名单的行为的发现,标志着我们对 Deepin 评估的一个转折点。我们不认为 openSUSE Deepin 打包者在实施“许可协议”对话框以绕过我们的白名单限制时出于恶意。该对话框本身使我们对安全性的担忧透明化,至少对用户而言,这并不是偷偷摸摸的。然而,它没有与我们讨论过,并且违反了 openSUSE 的打包策略。除了安全方面,这也影响了总体打包质量保证:例如,deepin-feature-enable 软件包安装的 D-Bus 配置文件和 Polkit 策略是软件包管理器不知道的,并且在卸载软件包时不会被清理。我们认为此类绕过是不可接受的。

这些因素的结合促使我们决定将 Deepin 桌面环境完全从 openSUSE Tumbleweed 和未来的 Leap 16.0 版本中移除。在 openSUSE Leap 15.6 中,我们将只移除违规的 deepin-feature-enable 软件包。这是一个艰难的决定,因为 Deepin 桌面环境有相当多的用户。然而,我们坚信 Deepin 在 openSUSE 中的打包和安全评估需要一次重大的改革,最好是引入新的人员,他们可以帮助完善 Deepin 软件包,与 Deepin 上游建立关系,并关注错误修复,从而避免浪费我们时间的徒劳的后续审查。在这样的新设置下,我们愿意逐一审查所有敏感的 Deepin 组件。

当然,这个过程需要时间,而且作为安全团队,我们的能力是有限的。考虑到 Deepin 项目的规模,我们也希望看到其他 Linux 发行版和(安全)社区加入我们,努力与 Deepin 上游建立更好的安全文化。

在发布本报告后,我们收到了 Deepin 上游的电子邮件回复,他们也在一篇博文中对此事发表了看法,内容与此类似。他们概述了一个改进 Deepin 安全态度的行动计划,并计划在 2025 年 5 月底前解决我们报告的所有未解决问题。

5)如何在 openSUSE 上继续使用 Deepin

鉴于 Deepin 的安全记录以及上一节中表达的担忧,我们目前不建议使用 Deepin 桌面环境。如果您仍然希望在 openSUSE Tumbleweed 上安装(或继续使用)Deepin 桌面环境,尽管存在现有的安全担忧,您可以按照以下方法将 Deepin devel 项目仓库添加到您的系统:

# add the devel project repository for Deepin to zypper
# for other distributions you need to adjust the URL here to point to the proper repository for your case
root# zypper ar https://download.opensuse.org/repositories/X11:/Deepin:/Factory/openSUSE_Tumbleweed deepin-factory
# refresh zypper repositories
root# zypper ref
New repository or package signing key received:

  Repository:       deepin-factory
  Key Fingerprint:  EED7 FE07 D0FC DEF0 E5B4 D4A9 C0DA 4428 1599 EA1E
  Key Name:         X11:Deepin:Factory OBS Project <X11:Deepin:Factory@build.opensuse.org>
  Key Algorithm:    RSA 2048
  Key Created:      Sat Apr 29 01:27:01 2023
  Key Expires:      Mon Jul  7 01:27:01 2025
  Rpm Name:         gpg-pubkey-1599ea1e-644c5645



    Note: Signing data enables the recipient to verify that no modifications occurred after the data
    were signed. Accepting data with no, wrong or unknown signature can lead to a corrupted system
    and in extreme cases even to a system compromise.

    Note: A GPG pubkey is clearly identified by its fingerprint. Do not rely on the key\'s name. If
    you are not sure whether the presented key is authentic, ask the repository provider or check
    their web site. Many providers maintain a web page showing the fingerprints of the GPG keys they
    are using.

Do you want to reject the key, trust temporarily, or trust always? [r/t/a/?] (r):

该项目的当前 GPG 密钥指纹为 EED7 FE07 D0FC DEF0 E5B4 D4A9 C0DA 4428 1599 EA1E。您可以通过下载公钥,使用 gpg --import 导入它,并检查新导入密钥的 gpg --fingerprint 输出,来自己验证。

请注意,这样做意味着您将信任来自此 devel 项目的任何软件包,这些软件包既未经过 SUSE 安全团队的审查,也未经过 openSUSE 软件包提交审查团队的审查。

对于 openSUSE Leap,您需要将仓库 URL 调整为指向适合您系统的正确 Leap 仓库。

6) 参考资料

专门的安全报告

审查错误

变更历史

2025-05-08 第 3 节)2019-05-05:deepin-file-manager第 3 节)2023-05-13:deepin-app-services进行了微调。修正了第 5 节)中的一个错别字。
2025-05-14 第 4 节)的末尾添加了关于上游对本报告响应的说明。