diff --git a/common/fileutil/fileutil.go b/common/fileutil/fileutil.go new file mode 100644 index 000000000..f0c45c432 --- /dev/null +++ b/common/fileutil/fileutil.go @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +package fileutil + +import ( + "fmt" + "io" + "os" + + "golang.org/x/sys/unix" +) + +// SafeReadFile 安全读取文件,拒绝符号链接 +func SafeReadFile(filename string) ([]byte, error) { + fi, err := os.Lstat(filename) + if err != nil { + return nil, err + } + if fi.Mode()&os.ModeSymlink != 0 { + return nil, fmt.Errorf("file %q is a symlink, refusing to follow", filename) + } + if !fi.Mode().IsRegular() { + return nil, fmt.Errorf("file %q is not a regular file", filename) + } + + f, err := os.OpenFile(filename, unix.O_RDONLY|unix.O_NOFOLLOW, 0) + if err != nil { + return nil, err + } + defer f.Close() + return io.ReadAll(f) +} + +// SafeWriteFile 安全写入文件,拒绝符号链接 +func SafeWriteFile(filename string, content []byte, perm os.FileMode) error { + fi, err := os.Lstat(filename) + if err != nil && !os.IsNotExist(err) { + return err + } + if err == nil { + // 文件已存在,必须是普通文件 + if fi.Mode()&os.ModeSymlink != 0 { + return fmt.Errorf("file %q is a symlink, refusing to write", filename) + } + if !fi.Mode().IsRegular() { + return fmt.Errorf("file %q is not a regular file", filename) + } + f, err := os.OpenFile(filename, unix.O_WRONLY|unix.O_TRUNC|unix.O_NOFOLLOW, perm) + if err != nil { + return err + } + defer f.Close() + _, err = f.Write(content) + return err + } + // 文件不存在,安全创建 + f, err := os.OpenFile(filename, unix.O_WRONLY|unix.O_CREAT|unix.O_EXCL, perm) + if err != nil { + return err + } + defer f.Close() + _, err = f.Write(content) + return err +} diff --git a/keybinding1/utils.go b/keybinding1/utils.go index 4070e4835..1e55cf8d5 100644 --- a/keybinding1/utils.go +++ b/keybinding1/utils.go @@ -20,6 +20,7 @@ import ( dbus "github.com/godbus/dbus/v5" "github.com/linuxdeepin/dde-daemon/keybinding1/constants" "github.com/linuxdeepin/dde-daemon/keybinding1/util" + "github.com/linuxdeepin/dde-daemon/common/fileutil" wm "github.com/linuxdeepin/go-dbus-factory/session/com.deepin.wm" gio "github.com/linuxdeepin/go-gir/gio-2.0" @@ -31,10 +32,10 @@ import ( const ( suspendStateUnknown = iota + 1 suspendStateLidOpen + suspendStateLidClose suspendStateFinish suspendStateWakeup suspendStatePrepare - suspendStateLidClose suspendStateButtonClick ) @@ -287,6 +288,9 @@ func (m *Manager) systemShutdown() { } func (m *Manager) systemTurnOffScreen() { + if isDpmsOff() { + return + } logger.Info("DPMS Off") var err error var useWayland bool @@ -327,7 +331,16 @@ func (m *Manager) systemTurnOffScreen() { m.setWmBlackScreenActive(false) } undoPrepareSuspend() - os.WriteFile("/tmp/dpms-state", []byte("1"), 0644) + fileutil.SafeWriteFile("/tmp/dpms-state", []byte("1"), 0600) +} + +func isDpmsOff() bool { + content, err := fileutil.SafeReadFile("/tmp/dpms-state") + if err != nil { + logger.Debug("read dpms state error:", err) + return false + } + return bytes.Equal(bytes.TrimSpace(content), []byte("1")) } func (m *Manager) systemLogout() { diff --git a/session/power1/power_save_plan.go b/session/power1/power_save_plan.go index 6ef763fce..2ca32a647 100644 --- a/session/power1/power_save_plan.go +++ b/session/power1/power_save_plan.go @@ -13,6 +13,8 @@ import ( "os/exec" "strings" "sync" + + "github.com/linuxdeepin/dde-daemon/common/fileutil" "time" "github.com/godbus/dbus/v5" @@ -1059,15 +1061,15 @@ func (psp *powerSavePlan) startIdleTasksLocked() { } func (ps *powerSavePlan) restoreDpmsStateFile() { - v, err := os.ReadFile("/tmp/dpms-state") + v, err := fileutil.SafeReadFile("/tmp/dpms-state") if err != nil { return } if string(v) == "1" { - err = os.WriteFile("/tmp/dpms-state", []byte("0"), 0644) + err = fileutil.SafeWriteFile("/tmp/dpms-state", []byte("0"), 0600) if err != nil { - logger.Warning("WriteFile /tmp/dpms-state:", err) + logger.Warning("write dpms state:", err) } } } diff --git a/session/power1/utils.go b/session/power1/utils.go index 6d967e050..59f9926f0 100644 --- a/session/power1/utils.go +++ b/session/power1/utils.go @@ -6,13 +6,13 @@ package power import ( "math" - "os" "os/exec" "strings" "time" dbus "github.com/godbus/dbus/v5" "github.com/linuxdeepin/dde-api/soundutils" + "github.com/linuxdeepin/dde-daemon/common/fileutil" . "github.com/linuxdeepin/go-lib/gettext" "github.com/linuxdeepin/go-lib/pulse" "github.com/linuxdeepin/go-x11-client/ext/dpms" @@ -210,7 +210,7 @@ func (m *Manager) setDPMSModeOff() { } else { callSetScreenState(true) } - os.WriteFile("/tmp/dpms-state", []byte("1"), 0644) + fileutil.SafeWriteFile("/tmp/dpms-state", []byte("1"), 0600) } const (