Fix security - #1199
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: fly602 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideIntegrates deepin-security-loader into multiple daemons and hardware-control paths, introducing an allow-caller registry that enforces DBus caller authorization per scope with a Polkit fallback, wiring it through airplane mode, power, system-daemon, input devices, and langselector, plus packaging and DBus policy updates to run certain binaries via loader wrappers. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
0bb9d87 to
e02c924
Compare
1. 新增 securityloader 模块,实现与 deepin-security-loader 的文件描述符 通信握手机制,解析并清理注入的启动参数 2. 将 dde-session-daemon 二进制文件安装路径从 /usr/lib/deepin-daemon 迁 移至 /usr/libexec/deepin/,原路径替换为 loader-wrapper 脚本以实现安全 加载 3. 在 dde-system-daemon 和 system/power 模块中引入 AllowCallerRegistry, 新增 SetAllowCaller DBus 方法用于动态注册受信任的调用方唯一名称 4. 对 SetIdleState、SetScreenState 和 SetTlpMode 等敏感接口增加权限校 验,拦截非 root 且未在 AllowCallerRegistry 中注册的 DBus 调用 5. 实现 AllowCallerRegistry 状态的 JSON 持久化,通过比对系统总线 BusID 防止跨重启周期的无效授权,并监听 NameOwnerChanged 信号自动清理断开连接的 调用方 6. 更新 DBus 策略配置,严格限制 SetAllowCaller 方法仅允许 root 用户和 deepin-daemon 组调用,并在 default 策略中显式拒绝 7. 在 debian 和 rpm 打包规则中新增 deepin-security-loader 依赖,并添加相 关单元测试 Influence: 1. 验证 dde-session-daemon 能否通过 wrapper 脚本正常启动,并确认启动日志 中无 security-loader handshake failed 错误 2. 测试 dde-session-daemon 正常启动后 Task: https://pms.uniontech.com/task-view-393313.html
1. 在 InputDevices 和 Touchpad 模块中集成 securityloader 的 AllowCaller 机制以增强安全性 2. 为 SetTouchpadEnable 接口增加 DBus Sender 权限校验防止恶意调用 3. 新增并导出 SetAllowCaller 接口供受信任的系统服务进行调用者身份注册 4. 更新 DBus 策略配置限制仅 root 和 deepin-daemon 组可调用 SetAllowCaller 并在默认策略中拒绝其他未授权访问 5. 在 session-daemon 启动阶段注册 InputDevices 的安全作用域 Task: https://pms.uniontech.com/task-view-393313.html
1. 移除飞行模式模块中原有的基于 polkit 的同步鉴权逻辑及相关的依赖 2. 引入并集成 securityloader 的 AllowCallerRegistry 白名单鉴权机制,增加 AirplaneModeScope 常量定义 3. 导出 SetAllowCaller 接口,并在 dde-session-daemon 中添加该接口的 DBus 配置以完成权限注册 4. 修改 DBus 策略配置文件,严格限制 SetAllowCaller 方法仅允许 root 用户 和 deepin-daemon 组访问,并在默认策略中增加拒绝规则 5. 修改 Enable、EnableWifi、EnableBluetooth 三个核心方法的权限校验方式, 由原来的 polkit 交互式鉴权改为统一白名单校验,并补充鉴权失败时的日志记录 Task: https://pms.uniontech.com/task-view-393313.html
dde-session-daemon 启动时将 org.deepin.dde.Lastore1.Manager 加入 security-loader 握手目标,使当前进程的 system bus unique name 通过 lastore-daemon 的 SetAllowCaller 注册为受信任调用者。 lastore Agent 调用 RegisterAgent 和 UnRegisterAgent 时复用该 system bus 连接,从而走 allow-caller 鉴权,避免弹出 polkit 交互认证框。 Log: 为 lastore Agent 注册适配 security-loader Influence: lastore Agent 注册、注销及更新通知功能 Task: https://pms.uniontech.com/task-view-393313.html
1. 在 securityloader.go 的 defaultDestList 中新增了 LocaleHelper 的 D-Bus 配置项 2. 包含其 DbusName、DbusPath 和 DbusInterface 的具体定义 3. 此改动是为了将 LocaleHelper 服务纳入安全握手机制的白名单中,确保系统语 言选择器能够正常与 LocaleHelper 进行安全通信,避免因权限校验导致的 D-Bus 调用失败 历史相关:迁移 v20 中 langselector securityloader 完整握手机制 (含 cfd01e630 控制中心切换语言弹鉴权窗、e29680ba3 修复切换语言不生效 两笔历史提交),D-Bus 接口名适配 v25 风格: - com.deepin.api.LocaleHelper -> org.deepin.dde.LocaleHelper1 - com.deepin.daemon.Accounts -> org.deepin.dde.Accounts1 - com.deepin.lastore -> org.deepin.dde.Lastore1 Influence: 1. 测试系统语言或区域设置的切换功能是否正常生效 2. 验证语言选择器与LocaleHelper之间的D-Bus通信是否畅通无阻 3. 检查系统日志中是否还存在与LocaleHelper相关的D-Bus权限拒绝或安全握手失 败的报错 4. 回归测试语言选择器的其他基础功能,确保新增配置未对原有服务通信造成 干扰 Log: 切换语言仅允许dde-session-daemon调用 Task: https://pms.uniontech.com/task-view-393313.html
当服务未通过 deepin-security-loader 启动时,AllowCaller 白名单未启用, SetTouchpadEnable、SetTlpMode、SetIdleState、SetScreenState 等接口 回退到 polkit 认证提权,保证非安全加载场景下功能可用。 新增 polkit 策略 org.deepin.dde.hardware-control: - org.deepin.dde.inputdevices.set-touchpad: 触控板开关 - org.deepin.dde.daemon.set-idle-state: 设置空闲状态 - org.deepin.dde.daemon.set-screen-state: 设置屏幕状态 SetTlpMode 复用已有 org.deepin.dde.power.doAction 策略。 Task: https://pms.uniontech.com/task-view-393313.html
1. 为 dde-system-daemon 配置 /run/dde-daemon 运行目录及状态保留, 使 AllowCaller 状态在 ProtectSystem=strict 下可写 2. 将 dde-session-daemon 用户服务改为 forking 模式,由 systemd 接管 security-loader 启动的真实进程,并等待 D-Bus 名称就绪 3. wrapper 检查 loader 及 CAP_SETGID,不可用时直接启动真实进程, 由原有 polkit 鉴权路径回退 Influence: 1. 验证 dde-system-daemon 启动及重启后 /run/dde-daemon 权限正确, AllowCaller 状态可写入和恢复 2. 验证 dde-session-daemon 通过 security-loader 启动后服务保持 active, MainPID 指向真实进程且 D-Bus 名称正常就绪 3. 验证 Daemon1、Lastore1、InputDevices1 和 AirplaneMode1 的调用方 注册成功,日志中无 read-only file system 错误 4. 验证 loader 缺失或 CAP_SETGID 不可用时可直接启动,并使用原有 polkit 鉴权路径 5. 验证服务停止、异常退出和自动重启时无残留进程 Task: https://pms.uniontech.com/task-view-393313.html
deepin pr auto review★ 总体评分:35分■ 【总体评价】
■ 【详细分析】
■ 【改进建议代码示例】 // securityloader/allowcaller.go - 修复 authorizeRegistrar 中的 root 信任绕过
func (r *AllowCallerRegistry) authorizeRegistrar(sender dbus.Sender, uniqueName string) error {
senderUID, err := r.service.GetConnUID(string(sender))
if err != nil {
return fmt.Errorf("get SetAllowCaller sender %s UID failed: %w", sender, err)
}
// 移除对 root 的无条件信任,统一执行进程祖先校验
if r.privilegedGroupID == invalidGroupID {
return fmt.Errorf("privileged group %s is unavailable", privilegedGroup)
}
groups, err := r.service.GetConnGroups(string(sender))
if err != nil {
return fmt.Errorf("get SetAllowCaller sender %s groups failed: %w", sender, err)
}
if !containsGroup(groups, r.privilegedGroupID) {
return fmt.Errorf("D-Bus caller %s is not in privileged group %s", sender, privilegedGroup)
}
targetUID, err := r.service.GetConnUID(uniqueName)
if err != nil {
return fmt.Errorf("get target caller %s UID failed: %w", uniqueName, err)
}
if targetUID != senderUID {
return fmt.Errorf("SetAllowCaller sender UID %d does not own target %s with UID %d", senderUID, uniqueName, targetUID)
}
senderPID, err := r.service.GetConnPID(string(sender))
if err != nil {
return fmt.Errorf("get SetAllowCaller sender %s PID failed: %w", sender, err)
}
targetPID, err := r.service.GetConnPID(uniqueName)
if err != nil {
return fmt.Errorf("get target caller %s PID failed: %w", uniqueName, err)
}
if r.processParent == nil {
return errors.New("process ancestry resolver is unavailable")
}
isDescendant, err := isProcessDescendant(targetPID, senderPID, r.processParent)
if err != nil {
return fmt.Errorf("verify target caller %s process ancestry failed: %w", uniqueName, err)
}
if !isDescendant {
return fmt.Errorf(
"target caller %s PID %d is not a descendant of SetAllowCaller sender %s PID %d",
uniqueName, targetPID, sender, senderPID,
)
}
return nil
} |
|
@fly602: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Summary by Sourcery
Integrate deepin-security-loader into system daemons and hardware-control services to enforce caller-based authorization while preserving existing Polkit fallback.
New Features:
Bug Fixes:
Enhancements:
Build:
Tests:
Chores: