mirror of
https://github.com/cexll/myclaude.git
synced 2026-02-13 03:31:49 +08:00
fix: 增强日志清理的安全性和可靠性
必须修复的问题: 1. PID重用防护 - 添加进程启动时间检查,对比文件修改时间避免误删活动进程的日志 - Unix: 通过 /proc/<pid>/stat 读取进程启动时间 - Windows: 使用 GetProcessTimes API 获取创建时间 - 7天策略: 无法获取进程启动时间时,超过7天的日志视为孤儿 2. 符号链接攻击防护 - 新增安全检查避免删除恶意符号链接 - 使用 os.Lstat 检测符号链接 - 使用 filepath.EvalSymlinks 解析真实路径 - 确保所有文件在 TempDir 内(防止路径遍历) 强烈建议的改进: 3. 异步启动清理 - 通过 goroutine 运行清理避免阻塞主流程启动 4. NotExist错误语义修正 - 文件已被其他进程删除时计入 Kept 而非 Deleted - 更准确反映实际清理行为 - 避免并发清理时的统计误导 5. Windows兼容性验证 - 完善Windows平台的进程时间获取 测试覆盖: - 更新所有测试以适配新的安全检查逻辑 - 添加 stubProcessStartTime 支持PID重用测试 - 修复 setTempDirEnv 解析符号链接避免安全检查失败 - 所有测试通过(codex-wrapper: ok 6.183s) Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -14,7 +16,12 @@ const (
|
||||
stillActive = 259 // STILL_ACTIVE exit code
|
||||
)
|
||||
|
||||
var findProcess = os.FindProcess
|
||||
var (
|
||||
findProcess = os.FindProcess
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
getProcessTimes = kernel32.NewProc("GetProcessTimes")
|
||||
fileTimeToUnixFn = fileTimeToUnix
|
||||
)
|
||||
|
||||
// isProcessRunning returns true if a process with the given pid is running on Windows.
|
||||
func isProcessRunning(pid int) bool {
|
||||
@@ -42,3 +49,39 @@ func isProcessRunning(pid int) bool {
|
||||
|
||||
return exitCode == stillActive
|
||||
}
|
||||
|
||||
// getProcessStartTime returns the start time of a process on Windows.
|
||||
// Returns zero time if the start time cannot be determined.
|
||||
func getProcessStartTime(pid int) time.Time {
|
||||
if pid <= 0 {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
handle, err := syscall.OpenProcess(processQueryLimitedInformation, false, uint32(pid))
|
||||
if err != nil {
|
||||
return time.Time{}
|
||||
}
|
||||
defer syscall.CloseHandle(handle)
|
||||
|
||||
var creationTime, exitTime, kernelTime, userTime syscall.Filetime
|
||||
ret, _, _ := getProcessTimes.Call(
|
||||
uintptr(handle),
|
||||
uintptr(unsafe.Pointer(&creationTime)),
|
||||
uintptr(unsafe.Pointer(&exitTime)),
|
||||
uintptr(unsafe.Pointer(&kernelTime)),
|
||||
uintptr(unsafe.Pointer(&userTime)),
|
||||
)
|
||||
|
||||
if ret == 0 {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
return fileTimeToUnixFn(creationTime)
|
||||
}
|
||||
|
||||
// fileTimeToUnix converts Windows FILETIME to Unix time.
|
||||
func fileTimeToUnix(ft syscall.Filetime) time.Time {
|
||||
// FILETIME is 100-nanosecond intervals since January 1, 1601 UTC
|
||||
nsec := ft.Nanoseconds()
|
||||
return time.Unix(0, nsec)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user