Repository navigation
fix(power): read procfs credentials before checking EOF - #197
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideFix power-system caller authorization on procfs by reading credential data before EOF checks, normalizing Gid/Groups whitespace, and validating numeric gids; this restores legitimate loader authorization and prevents unnecessary polkit prompts. Sequence diagram for power caller authorization via procfssequenceDiagram
participant Loader as deepin-security-loader
participant Power as power-system
participant Procfs as procfs_status
participant Policy as CallerPolicy
Loader->>Power: SetAllowCaller()
Power->>Procfs: processHasGroup()
Procfs-->>Power: Gid/Groups match
Power->>Procfs: readParentPid()
Procfs-->>Power: PPid
Power->>Policy: addAllowedCaller()
Policy-->>Power: caller authorized
Flow diagram for procfs credential parsingflowchart TD
A[Open /proc/<pid>/status] --> B[Read first line]
B --> C{Data is empty?}
C -- Yes --> D[Return false]
C -- No --> E{Gid or Groups line?}
E -- No --> B
E -- Yes --> F[Normalize whitespace]
F --> G[Parse numeric fields]
G --> H{Matching gid found?}
H -- Yes --> I[Return true]
H -- No --> B
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
b2eb63e to
d232dd6
Compare
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
d232dd6 to
36e6044
Compare
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 语法正确,逻辑清晰。for 循环模式 (QByteArray data = file.readLine(); !data.isEmpty(); data = file.readLine()) 正确处理了 procfs 文件大小为 0 的情况。toUInt(&ok) 的 ok 标志检查正确防止了非数字字符串的误匹配。simplified() 正确归一化了空白字符。边界条件处理完善:空文件时循环不执行返回 false,无匹配行时循环耗尽返回 false。 2. 代码质量 ✅评价: 优秀 ✅ 通过 潜在问题:
建议: 代码结构清晰,注释完整。建议在 readParentPid() 函数中添加与 processHasGroup() 相同的 procfs 行为说明注释,提高代码可维护性。两个函数的读取循环模式一致,可考虑未来提取为公共辅助函数。 3. 代码性能 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 性能良好,资源使用合理。修改后将 QString::fromLatin1() 转换延迟到匹配行才执行,避免了非匹配行的 unnecessary 字符串转换。QByteArray::startsWith() 比 QString::startsWith(QLatin1String()) 更高效。无不必要的内存分配。 4. 代码安全 🔒评价: 优秀 ✅ 通过
安全漏洞详情: 建议: 漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个。存在0个安全漏洞。本次修改实际上是安全增强:toUInt(&ok) 的 ok 标志检查防止了非数字字段被转换为 0 后误匹配 gid 0(root 组),避免了潜在的权限提升风险。无硬编码凭据,无注入风险,无敏感信息泄露。 💡 改进建议代码示例// 建议在 readParentPid() 中添加注释,与 processHasGroup() 保持一致
static bool readParentPid(uint pid, uint &parent)
{
QFile file(QString::fromLatin1("/proc/%1/status").arg(pid));
if (!file.open(QIODevice::ReadOnly))
return false;
// 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("PPid:"))
continue;
const QString line = QString::fromLatin1(data);
bool ok = false;
parent = line.section(QLatin1Char(':'), 1).trimmed().toUInt(&ok);
return ok;
}
return false;
}本报告由 AI 代码审查工具自动生成 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: fly602, mhduiy 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 |
|
/forcemerge |
|
This pr force merged! (status: blocked) |
fix: read procfs credentials before checking EOF
QFile::atEnd(); procfs reports size 0, so atEnd() is already true
before the first read.
ignore non numeric fields so gid 0 cannot be matched by a gap.
check performed when a caller registers itself.
Log: Restore passwordless caller registration for the power service
Influence:
power_allow_callers.json should now exist and list the session bus
unique name.
dde-session at login.
no administrator password dialog should be left behind.
confirm no polkit prompt appears.
fix: 修正 procfs 凭据读取,恢复免密授权注册
大小为 0,首次读取前 atEnd() 已为真。
避免空字段被当作 gid 0 匹配。
父子关系的基础。
Log: 恢复电源服务调用方的免密注册
Influence:
power_allow_callers.json 应生成并包含会话的系统总线唯一名。
"invalid caller :1.x"。
密码认证弹窗。
PMS: BUG-379055
Summary by Sourcery
Restore passwordless power-service authorization by making procfs credential and process ancestry checks reliable.
Bug Fixes:
Enhancements: