From 36e604498a46c5b1f059851545209996baac4931 Mon Sep 17 00:00:00 2001 From: fuleyi Date: Thu, 15 Oct 2026 17:36:00 +0800 Subject: [PATCH] fix: read procfs credentials before checking EOF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Read the first line before testing for EOF, instead of relying on QFile::atEnd(); procfs reports size 0, so atEnd() is already true before the first read. 2. Normalize whitespace so the tab separated Gid field parses too, and ignore non numeric fields so gid 0 cannot be matched by a gap. 3. Use the same read loop in readParentPid(), which backs the descendant check performed when a caller registers itself. Log: Restore passwordless caller registration for the power service Influence: 1. Upgrade dde-services and log in again: /run/dde-services/ power_allow_callers.json should now exist and list the session bus unique name. 2. User journal should no longer log "invalid caller :1.x" for dde-session at login. 3. Hibernate from one logged in user, resume, switch to the other user: no administrator password dialog should be left behind. 4. Switch the power mode from control center in an active session and confirm no polkit prompt appears. fix: 修正 procfs 凭据读取,恢复免密授权注册 1. 改为先读取一行再判断结束,不再依赖 QFile::atEnd():procfs 文件 大小为 0,首次读取前 atEnd() 已为真。 2. 归一化空白字符,使制表符分隔的 Gid 字段可解析;忽略非数字字段, 避免空字段被当作 gid 0 匹配。 3. readParentPid() 采用同样的读取方式,它是调用方注册时判断进程 父子关系的基础。 Log: 恢复电源服务调用方的免密注册 Influence: 1. 升级 dde-services 后重新登录,/run/dde-services/ power_allow_callers.json 应生成并包含会话的系统总线唯一名。 2. 登录阶段用户日志中不再出现 dde-session 的 "invalid caller :1.x"。 3. 在一个用户会话中休眠,唤醒后切到另一个用户,确认不再残留管理员 密码认证弹窗。 4. 活动会话中通过控制中心切换电源模式,确认无 polkit 弹窗。 PMS: BUG-379055 --- src/plugin-qt/power/system/powermanager.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/plugin-qt/power/system/powermanager.cpp b/src/plugin-qt/power/system/powermanager.cpp index c6cad4f3..89c6e7e0 100644 --- a/src/plugin-qt/power/system/powermanager.cpp +++ b/src/plugin-qt/power/system/powermanager.cpp @@ -82,13 +82,15 @@ static bool processHasGroup(uint pid, gid_t gid) if (!file.open(QIODevice::ReadOnly)) return false; - while (!file.atEnd()) { - const QString line = QString::fromLatin1(file.readLine()); - if (!line.startsWith(QLatin1String("Gid:")) && !line.startsWith(QLatin1String("Groups:"))) + // procfs reports size zero, so atEnd() is true even before the first read. + for (QByteArray data = file.readLine(); !data.isEmpty(); data = file.readLine()) { + if (!data.startsWith("Gid:") && !data.startsWith("Groups:")) continue; - const QStringList values = line.section(QLatin1Char(':'), 1).split(QChar::Space, Qt::SkipEmptyParts); + const QString line = QString::fromLatin1(data); + const QStringList values = line.section(QLatin1Char(':'), 1).simplified().split(QChar::Space, Qt::SkipEmptyParts); for (const QString &value : values) { - if (value.toUInt() == gid) + bool ok = false; + if (value.toUInt(&ok) == gid && ok) return true; } } @@ -101,10 +103,10 @@ static bool readParentPid(uint pid, uint &parent) if (!file.open(QIODevice::ReadOnly)) return false; - while (!file.atEnd()) { - const QString line = QString::fromLatin1(file.readLine()); - if (!line.startsWith(QLatin1String("PPid:"))) + for (QByteArray data = file.readLine(); !data.isEmpty(); data = file.readLine()) { + if (!data.startsWith("PPid:")) continue; + const QString line = QString::fromLatin1(data); bool ok = false; parent = line.section(QLatin1Char(':'), 1).trimmed().toUInt(&ok); return ok;