From fc2635d0ed10be94aceab22bad9c4fe2889353d4 Mon Sep 17 00:00:00 2001 From: chenyuanbo Date: Mon, 29 Jun 2026 14:25:40 +0800 Subject: [PATCH 1/3] fix: improve temporary background file creation in theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Removed unused imports (filepath, utils) and cleaned up import references 2. Changed temporary file creation from hardcoded path to using os.CreateTemp with a safe filename pattern 3. Simplified the if-else logic by removing unnecessary else block and using early return 4. Used path.Ext for extension extraction instead of filepath.Ext This refactoring ensures that temporary background files are created using Go's standard safe method, which provides random naming to avoid collisions and potential race conditions. The previous approach used a hardcoded filename which could cause conflicts if multiple instances run simultaneously. Influence: 1. Verify that setting a background source file works correctly via DBus 2. Test getting the background returns a valid temporary file path 3. Verify the temporary file has the correct extension matching the source 4. Check that temporary files are properly cleaned up 5. Test concurrent operations to ensure no file name collisions 6. Verify that the temporary file is readable and contains valid image data refactor: 改进主题中的临时背景文件创建 1. 移除未使用的导入(filepath, utils)并清理导入引用 2. 将临时文件创建从硬编码路径改为使用 os.CreateTemp 并使用安全的文件名 模式 3. 通过移除不必要的 else 块和使用提前返回来简化 if-else 逻辑 4. 使用 path.Ext 替代 filepath.Ext 进行扩展名提取 这次重构确保使用 Go 标准的安全方法创建临时背景文件,通过随机命名避免冲突 和潜在的竞争条件。之前的方法使用硬编码文件名,如果多个实例同时运行可能导 致冲突。 Influence: 1. 验证通过 DBus 设置背景源文件功能正常 2. 测试获取背景返回有效的临时文件路径 3. 验证临时文件具有与源文件匹配的正确扩展名 4. 检查临时文件是否被正确清理 5. 测试并发操作以确保文件名无冲突 6. 验证临时文件可读且包含有效的图像数据 PMS: BUG-367561 (cherry picked from commit 72bacd97433a00de16921d933ae424dcc59f3fb1) --- grub2/theme_ifc.go | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/grub2/theme_ifc.go b/grub2/theme_ifc.go index e1aef3ee1..206a44818 100644 --- a/grub2/theme_ifc.go +++ b/grub2/theme_ifc.go @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -8,13 +8,11 @@ import ( "os" "os/exec" "path" - "path/filepath" "strings" "github.com/godbus/dbus/v5" "github.com/linuxdeepin/go-lib/dbusutil" "github.com/linuxdeepin/go-lib/utils" - dutils "github.com/linuxdeepin/go-lib/utils" ) const ( @@ -79,19 +77,35 @@ func (theme *Theme) GetBackground(sender dbus.Sender) (background string, busErr if len(background) == 0 { return "", nil - } else { + } - tmpBackground := "dde-grub-background" + path.Ext(defaultGrubBackground) - backGroundTmpPath := filepath.Join("/tmp", tmpBackground) - //copy file to /tmp - err := dutils.CopyFile(background, backGroundTmpPath) - if err != nil { - return "", dbusutil.ToError(err) - } - logger.Debugf("Copy file %s to %s", background, backGroundTmpPath) + ext := path.Ext(background) + backGroundTmpFile, err := os.CreateTemp("/tmp", "dde-grub-background-*"+ext) + if err != nil { + return "", dbusutil.ToError(err) + } - return backGroundTmpPath, nil + backGroundTmpPath := backGroundTmpFile.Name() + backGroundTmpFile.Close() + + err = utils.CopyFile(background, backGroundTmpPath) + if err != nil { + logger.Warningf("GetBackground: copy %q to %q failed: %v", background, backGroundTmpPath, err) + _ = os.Remove(backGroundTmpPath) + return "", dbusutil.ToError(err) + } + + err = os.Chmod(backGroundTmpPath, 0644) + if err != nil { + logger.Warningf("GetBackground: chmod %q 0644 failed: %v", backGroundTmpPath, err) + _ = os.Remove(backGroundTmpPath) + return "", dbusutil.ToError(err) } + logger.Debugf("Copy file %s to %s", background, backGroundTmpPath) + + // 已知问题:返回的临时文件由调用方使用,本服务不清理。每次调用产生一个 + // 唯一命名的新文件,重复调用会在 /tmp 中累积(依赖重启清空 tmpfs)。 + return backGroundTmpPath, nil } func (theme *Theme) emitSignalBackgroundChanged() { From e577acdad265a18cb199822dbbe2db9ac28e039f Mon Sep 17 00:00:00 2001 From: xionglinlin Date: Tue, 30 Jun 2026 17:24:00 +0800 Subject: [PATCH 2/3] feat: add polkit authorization for uadp manager methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Add polkit rules file allowing lightdm active sessions to call the uadp action without password 2. Implement checkAuthorization function using polkit authority to verify caller authorization 3. Add authorization checks to all sensitive uadp methods: ListName, Set, Get, Delete, Release 4. Return empty results with authorization error when caller is not authorized Log: Added polkit authorization protection for uadp manager operations Influence: 1. Test all uadp methods (ListName, Set, Get, Delete, Release) with unauthorized caller 2. Verify lightdm active sessions can call methods without password prompt 3. Test lightdm inactive sessions are denied access 4. Verify polkit rules file is installed correctly 5. Test normal user calls with proper authorization prompt 6. Verify error handling when authorization is denied feat: 为 uadp 管理器方法添加 polkit 授权 1. 添加 polkit 规则文件,允许 lightdm 活跃会话无需密码调用 uadp 操作 2. 实现 checkAuthorization 函数,使用 polkit 权限验证调用者授权 3. 为所有敏感 uadp 方法添加授权检查:ListName、Set、Get、Delete、Release 4. 当调用者未授权时返回空结果和授权错误 Log: 为 uadp 管理操作添加 polkit 授权保护 Influence: 1. 使用未授权调用者测试所有 uadp 方法(ListName、Set、Get、Delete、 Release) 2. 验证 lightdm 活跃会话可无需密码调用方法 3. 测试 lightdm 非活跃会话被拒绝访问 4. 验证 polkit 规则文件正确安装 5. 测试普通用户调用时弹出授权提示 6. 验证授权被拒绝时的错误处理 PMS: BUG-367555 BUG-367575 Change-Id: I5a77779ab915aaae8fca23c25fda3173752aa5e4 (cherry picked from commit fdfc10109a25f8fdde933a2f0b40d57dbb611867) --- misc/polkit-rules/org.deepin.dde.uadp.rules | 17 ++++++ system/uadp1/manager.go | 59 ++++++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 misc/polkit-rules/org.deepin.dde.uadp.rules diff --git a/misc/polkit-rules/org.deepin.dde.uadp.rules b/misc/polkit-rules/org.deepin.dde.uadp.rules new file mode 100644 index 000000000..e24e6cf2a --- /dev/null +++ b/misc/polkit-rules/org.deepin.dde.uadp.rules @@ -0,0 +1,17 @@ +polkit.addRule(function(action, subject) { + if (action.id === "org.deepin.dde.uadp.doAction") { + // lightdm 活跃会话放行(greeter 免密码调用) + if (subject.user === "lightdm") { + if (subject.active) { + return polkit.Result.YES; + } else { + return polkit.Result.NO; + } + } + + // deepin-daemon 用户及组放行 + if (subject.user === "deepin-daemon" || subject.isInGroup("deepin-daemon")) { + return polkit.Result.YES; + } + } +}); diff --git a/system/uadp1/manager.go b/system/uadp1/manager.go index d33c3ecfc..1f54c7160 100644 --- a/system/uadp1/manager.go +++ b/system/uadp1/manager.go @@ -1,11 +1,14 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later package uadp import ( - "github.com/godbus/dbus/v5" + "errors" + + dbus "github.com/godbus/dbus/v5" + polkit "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.policykit1" "github.com/linuxdeepin/go-lib/dbusutil" "github.com/linuxdeepin/go-lib/procfs" ) @@ -16,6 +19,28 @@ import ( const uadpEncryptMaxSize = 256 - 11 const uadpDecryptMaxSize = 256 +const uadpActionId = "org.deepin.dde.uadp.doAction" + +func checkAuthorization(actionId string, sysBusName string) error { + systemBus, err := dbus.SystemBus() + if err != nil { + return err + } + authority := polkit.NewAuthority(systemBus) + subject := polkit.MakeSubject(polkit.SubjectKindSystemBusName) + subject.SetDetail("name", sysBusName) + + ret, err := authority.CheckAuthorization(0, subject, actionId, + nil, polkit.CheckAuthorizationFlagsAllowUserInteraction, "") + if err != nil { + return err + } + if !ret.IsAuthorized { + return errors.New("not authorized") + } + return nil +} + type Manager struct { service *dbusutil.Service @@ -60,6 +85,12 @@ func (m *Manager) Available() (bool, *dbus.Error) { } func (m *Manager) ListName(sender dbus.Sender) ([]string, *dbus.Error) { + err := checkAuthorization(uadpActionId, string(sender)) + if err != nil { + logger.Warning(err) + return []string{}, dbusutil.ToError(err) + } + exec, err := m.getExecPath(sender) if err != nil { logger.Warning(err) @@ -70,6 +101,12 @@ func (m *Manager) ListName(sender dbus.Sender) ([]string, *dbus.Error) { } func (m *Manager) Set(sender dbus.Sender, name string, data []byte) *dbus.Error { + err := checkAuthorization(uadpActionId, string(sender)) + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + exec, err := m.getExecPath(sender) if err != nil { logger.Warning(err) @@ -102,6 +139,12 @@ func (m *Manager) Set(sender dbus.Sender, name string, data []byte) *dbus.Error } func (m *Manager) Get(sender dbus.Sender, name string) ([]byte, *dbus.Error) { + err := checkAuthorization(uadpActionId, string(sender)) + if err != nil { + logger.Warning(err) + return []byte{}, dbusutil.ToError(err) + } + exec, err := m.getExecPath(sender) if err != nil { logger.Warning(err) @@ -123,6 +166,12 @@ func (m *Manager) Get(sender dbus.Sender, name string) ([]byte, *dbus.Error) { } func (m *Manager) Delete(sender dbus.Sender, name string) *dbus.Error { + err := checkAuthorization(uadpActionId, string(sender)) + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + exec, err := m.getExecPath(sender) if err != nil { logger.Warning(err) @@ -140,6 +189,12 @@ func (m *Manager) Delete(sender dbus.Sender, name string) *dbus.Error { } func (m *Manager) Release(sender dbus.Sender) *dbus.Error { + err := checkAuthorization(uadpActionId, string(sender)) + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + exec, err := m.getExecPath(sender) if err != nil { logger.Warning(err) From 2c899381ce7a6aa36b08190be26792b031625e65 Mon Sep 17 00:00:00 2001 From: chenyuanbo Date: Mon, 29 Jun 2026 17:36:30 +0800 Subject: [PATCH 3/3] fix: improve gfxmode signal file creation safety MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Move gfxmode signal file from /tmp to /run (tmpfs, wiped each boot) to fix stale-file issue that could prevent detection completion 2. Introduce CreateGfxmodeDetectReady function to centralize mkdir + write logic with consistent error wrapping 3. Remove direct os.WriteFile calls in favor of the new function 4. Update systemd service with RuntimeDirectory to manage /run/deepin-gfxmode-detect and preserve across restarts Log: Relocate gfxmode detection signal file to /run and unify creation entry for better lifecycle management PMS: BUG-367565 Influence: 1. Test gfxmode detection process with normal device conditions 2. Verify signal file creation in /run directory after detection 3. Verify signal file preservation across service restart 4. Verify postinst grub2 -prepare-gfxmode-detect creates signal file without systemd RuntimeDirectory refactor: 提升 gfxmode 信号文件创建安全性 1. 将 gfxmode 信号文件从 /tmp 迁移至 /run(tmpfs,每次开机清空), 修正残留旧文件导致探测完成判断失效的问题 2. 引入 CreateGfxmodeDetectReady 函数,统一 mkdir + 写文件逻辑并 规范错误包装 3. 移除直接的 os.WriteFile 调用,统一使用新函数 4. 更新 systemd 服务,通过 RuntimeDirectory 托管 /run/deepin-gfxmode-detect 父目录并跨重启保留 Log: 将 gfxmode 探测完成信号文件迁移至 /run 并统一创建入口,改善生命周期管理 PMS: BUG-367565 Influence: 1. 测试正常设备条件下的 gfxmode 检测流程 2. 验证检测完成后 /run 目录中信号文件的创建与生命周期 3. 验证服务重启后信号文件按 RuntimeDirectoryPreserve 行为保留 4. 验证 postinst 的 grub2 -prepare-gfxmode-detect 在无 systemd 托管时能正常创建信号文件 (cherry picked from commit a50e3aa7828716d7081983fa4c2ff0e414c429cb) --- grub2/grub2_ifc.go | 3 +-- grub2/main.go | 2 +- grub_common/common.go | 17 ++++++++++++++++- .../services/system/deepin-grub2.service | 4 +++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/grub2/grub2_ifc.go b/grub2/grub2_ifc.go index cffc8739a..1006e6b96 100644 --- a/grub2/grub2_ifc.go +++ b/grub2/grub2_ifc.go @@ -6,7 +6,6 @@ package grub2 import ( "errors" - "os" "strings" "github.com/godbus/dbus/v5" @@ -316,7 +315,7 @@ func (g *Grub2) PrepareGfxmodeDetect(sender dbus.Sender) *dbus.Error { g.addModifyTask(getModifyTaskPrepareGfxmodeDetect(gfxmodesStr)) - err = os.WriteFile(grub_common.GfxmodeDetectReadyPath, nil, 0644) + err = grub_common.CreateGfxmodeDetectReady() if err != nil { return dbusutil.ToError(err) } diff --git a/grub2/main.go b/grub2/main.go index bebd39257..b0772e8fa 100644 --- a/grub2/main.go +++ b/grub2/main.go @@ -81,7 +81,7 @@ func PrepareGfxmodeDetect() error { gfxmodesStr := joinGfxmodesForDetect(gfxmodes) getModifyFuncPrepareGfxmodeDetect(gfxmodesStr)(params) - err = os.WriteFile(grub_common.GfxmodeDetectReadyPath, nil, 0644) + err = grub_common.CreateGfxmodeDetectReady() if err != nil { return err } diff --git a/grub_common/common.go b/grub_common/common.go index c2a485786..cbc9b49fe 100644 --- a/grub_common/common.go +++ b/grub_common/common.go @@ -28,7 +28,7 @@ var logger = log.NewLogger("grub_common") const ( GrubParamsFile = "/etc/default/grub" DDEGrubParamsFile = "/etc/default/grub.d/11_dde.cfg" - GfxmodeDetectReadyPath = "/tmp/deepin-gfxmode-detect-ready" + GfxmodeDetectReadyPath = "/run/deepin-gfxmode-detect/ready" DeepinGfxmodeDetect = "DEEPIN_GFXMODE_DETECT" DeepinGfxmodeAdjusted = "DEEPIN_GFXMODE_ADJUSTED" DeepinGfxmodeNotSupported = "DEEPIN_GFXMODE_NOT_SUPPORTED" @@ -265,6 +265,21 @@ func (v Gfxmodes) SortDesc() { sort.Sort(sort.Reverse(v)) } +// CreateGfxmodeDetectReady 创建 gfxmode 探测完成信号文件。 +// +// MkdirAll 兜底 unit 外调用(如 postinst 的 `grub2 -prepare-gfxmode-detect`)——此时无 +// RuntimeDirectory 托管父目录;服务内调用时父目录已由 systemd 建好,MkdirAll 为 no-op。 +func CreateGfxmodeDetectReady() error { + dir := filepath.Dir(GfxmodeDetectReadyPath) + if err := os.MkdirAll(dir, 0755); err != nil { + return fmt.Errorf("failed to mkdir %s: %w", dir, err) + } + if err := os.WriteFile(GfxmodeDetectReadyPath, nil, 0644); err != nil { + return fmt.Errorf("failed to create %s: %w", GfxmodeDetectReadyPath, err) + } + return nil +} + func ShouldFinishGfxmodeDetect(params map[string]string) bool { if params[DeepinGfxmodeDetect] == "1" { _, err := os.Stat(GfxmodeDetectReadyPath) diff --git a/misc/systemd/services/system/deepin-grub2.service b/misc/systemd/services/system/deepin-grub2.service index 25a525b43..7d9c2aaf1 100644 --- a/misc/systemd/services/system/deepin-grub2.service +++ b/misc/systemd/services/system/deepin-grub2.service @@ -16,7 +16,9 @@ InaccessiblePaths=-/etc/pam.d #InaccessiblePaths=-/usr/share/uadp/ # 创建/etc/default/grub.d/11_dde.cfg ReadWritePaths=-/etc/default/grub.d -# 创建/tmp/deepin-gfxmode-detect-ready // TODO分析该文件是否有被其他进程使用,该文件存放需要修改 +# /run/deepin-gfxmode-detect/ready,作为 gfxmode 探测完成信号文件 +RuntimeDirectory=deepin-gfxmode-detect +RuntimeDirectoryPreserve=yes ReadWritePaths=-/tmp/ # /var/cache/deepin/grub2.log ReadWritePaths=-/var/cache/deepin