Skip to content

fix(apt): extend core package protection to prevent accidental removal#423

Merged
qiuzhiqian merged 1 commit into
masterfrom
fix-dde-package
May 20, 2026
Merged

fix(apt): extend core package protection to prevent accidental removal#423
qiuzhiqian merged 1 commit into
masterfrom
fix-dde-package

Conversation

@qiuzhiqian

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented May 20, 2026

Copy link
Copy Markdown

CLA Assistant Lite bot:
提交邮箱中包含我们的合作伙伴,但您似乎并非合作伙伴的成员或对接人,请联系相关对接人将您添加至组织之中,或由其重新发起 Pull Request。
The commit email domain belongs to one of our partners, but it seems you are not yet a member of the current organization, please contact the contact person to add you to the organization or let them submit the Pull Request.

xml seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: qiuzhiqian, zhaohuiw42

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

@qiuzhiqian qiuzhiqian merged commit 1e4e93b into master May 20, 2026
21 of 29 checks passed
@qiuzhiqian qiuzhiqian deleted the fix-dde-package branch May 20, 2026 08:04
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的 Git Diff 内容。本次修改将 APT 代理中检查卸载 DDE 桌面环境的关键字从 "Remv dde " 修改为了 "Remv deepin-desktop-environment-core "

以下是我从语法逻辑、代码质量、代码性能和代码安全四个维度提出的审查意见与改进建议:

1. 语法与逻辑

  • 匹配字符串的准确性:在 APT 的输出中,Remv 表示软件包被移除。将匹配目标从宽泛的 dde 改为具体的 deepin-desktop-environment-core 逻辑上是更严谨的,因为 dde 可能会误匹配其他以 dde 开头的非核心包(如 dde-daemon 等),而 deepin-desktop-environment-core 是核心元包,移除它通常意味着整个桌面环境将被破坏。
  • 潜在遗漏风险(逻辑漏洞):在 Debian/Deepin 的包管理机制中,deepin-desktop-environment-core 是一个依赖众多子包的元包。如果在某些操作中,用户仅仅卸载了某个极其核心的底层组件(例如 deepin-anythingstartdde),APT 可能会由于依赖链断裂而顺带卸载整个桌面环境,但此时 stdout 中的输出可能不包含 Remv deepin-desktop-environment-core(因为它是作为依赖被自动卸载的,有时 APT 不会显式列出被连带移除的元包名,而是列出其依赖的具体子包)。
    • 建议:建议确认在 APT 的模拟运行(apt remove -s 或类似操作)中,当桌面环境被破坏时,是否必定输出 Remv deepin-desktop-environment-core。如果可能,建议增加对其他核心组件(如 startdde)的并行判断,以提高拦截的覆盖率。

2. 代码质量

  • 硬编码的魔法字符串:代码中直接硬编码了 "Remv deepin-desktop-environment-core "。这种包名和 APT 的状态前缀散落在业务代码中,不利于后续维护。
    • 建议:将其提取为常量,并集中管理核心受保护的包名列表。如果未来受保护的包增加,只需修改常量切片即可,无需修改核心逻辑。
    const (
        AptActionRemove = "Remv "
    )
    
    // 受保护的核心包列表
    var protectedPackages = []string{
        "deepin-desktop-environment-core",
        "startdde", // 可以扩展其他核心包
    }

3. 代码性能

  • 多次 Contains 查找的效率问题:目前使用 bytes.Contains 进行全量字节扫描。当前只有一次匹配时性能尚可,但如果按照上述建议扩展了多个核心包的匹配,在 stdout 很大(APT 输出可能非常长)的情况下,多次调用 bytes.Contains 会导致该字节切片被多次遍历扫描。
    • 建议:如果未来需要匹配多个包名,建议使用 bufio.Scanner 按行读取 stdout,或者将 stdout 按行切分后进行前缀和关键字匹配。这样只需遍历一次长字符串。
    // 示例:按行扫描的优化思路(适用于多关键字匹配)
    scanner := bufio.NewScanner(stdout)
    for scanner.Scan() {
        line := scanner.Text()
        if strings.HasPrefix(line, AptActionRemove) {
            for _, pkg := range protectedPackages {
                if strings.Contains(line, pkg) {
                    c.IndicateFailed("removeDDE", "", true)
                    return
                }
            }
        }
    }

4. 代码安全

  • 日志与状态注入风险:虽然 bytes.Contains 只是做精确的字节匹配,不存在正则表达式的 ReDoS 风险,但 APT 的输出内容部分受外部软件包控制(例如包的描述信息)。如果某个恶意的第三方软件包在自身的元数据中故意包含了 "Remv deepin-desktop-environment-core " 字符串,可能会触发误报,导致正常的包管理操作被中断。
    • 建议:为了防范此类极端情况,匹配逻辑应尽可能严格。APT 的标准输出格式通常为:Remv package_name [arch] ...。因此,更安全的做法是提取出 Remv 后的第一个字段(即实际的包名),然后判断该包名是否在受保护列表中,而不是简单地在整行中 Contains
    // 更安全的匹配逻辑:提取包名进行精确比对
    line := strings.TrimSpace(scanner.Text())
    if strings.HasPrefix(line, AptActionRemove) {
        // 提取 Remv 后面的包名部分
        fields := strings.Fields(line)
        if len(fields) >= 2 {
            removedPkg := fields[1]
            for _, pkg := range protectedPackages {
                if removedPkg == pkg {
                    c.IndicateFailed("removeDDE", "", true)
                    return
                }
            }
        }
    }

总结

本次修改的出发点是正确的,提高了拦截的精准度。但为了代码的健壮性和可维护性,建议:

  1. 短期:确认 APT 卸载核心依赖时是否必定输出该元包名,防止逻辑绕过;将匹配字符串提取为常量。
  2. 长期:考虑将简单的 bytes.Contains 升级为按行解析并精确提取包名的逻辑,这不仅能解决潜在的误报安全问题,还能为未来增加更多受保护包名提供更好的性能和架构支撑。

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