# 仓库规则 — CVE-2026-111497

适用范围：在本仓库中工作的代理与人员。
优先级：安全高于速度。每个不可逆动作之前都要有备份，并在沙箱中对该操作本身做一次校验。

## 目的

本仓库持有一个可复用的修复代理，针对 **CVE-2026-111497**，即 Google Brotli 解码器中的越界
写入。其核心是 `src/` 中一组确定性的 bash 脚本；它们返回紧凑的、机器可读的判定结论，并把
语言模型的 token 开销压到最低。

## 职责边界

- `src/detect.sh` —— **只读。** 不修改任何软件包、服务或配置文件。
- `src/remediate.sh` —— 唯一的变更点。它执行备份、真实性闸门、试运行、安装以及消费者重启。
- `src/verify.sh` —— **只读。** 它确认实际达成的效果。

## 强制不变量

1. **变更前备份。** 在安装任何东西之前，`remediate.sh` 总是创建
   `/root/cve-2026-111497-fix-<timestamp>/`，其中放入旧 `.so` 文件、可下载的 `.deb`
   以及一份 `dpkg` 快照。
2. **真实性闸门。** 只有在确认候选版本的变更日志引用 `CVE-2026-111497` 之后才执行安装。
   否则脚本停止并上报。
3. **重启消费者。** 修复之后，任何进程都不得继续映射存有漏洞的 `libbrotlidec`。
   这一点通过 `/proc/*/maps` 与 inode 比对进行检查。
4. **仓库中零密钥。** 不得出现密钥、口令、令牌、真实 IP 地址或主机名。目标主机以
   `~/.ssh/config` 中的 SSH 别名传入。
5. **文件格式。** LF、无 BOM、UTF-8。`.sh` 文件以 `100755` 模式提交。
6. **`.ragraf/` 永不提交** —— 该规则写在根 `.gitignore` 中。

## 命令

```bash
# syntax check before delivery
bash -n src/common.sh src/detect.sh src/remediate.sh src/verify.sh

# field order is fixed: detect -> remediate -> verify
bash src/detect.sh ; echo "exit=$?"
bash src/remediate.sh
bash src/verify.sh
```

## 验证

仅当以下全部成立时，变更才会被接受：

```bash
bash -n src/*.sh                       # no syntax error
shellcheck src/*.sh                    # no unresolved finding
ghagent doc --root .                   # markdown and privacy contract
```

行为层面的证明是在一台可废弃主机上的现场运行：`detect.sh` 返回 `1`，随后 `remediate.sh`
返回 `0`，随后 `verify.sh` 打印 `VERIFY: PASS`。

## 提交顺序（由所有者执行，而非代理）

清除覆盖性变量并显式设置所有者身份：

```bash
unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
git -c user.name='Mikhail Deynekin' -c user.email='Mikhail@Deynekin.com' commit -m '...'
git log -1 --format='%an <%ae> | %cn <%ce>'   # owner, never zwork
```

## 陷阱

| 陷阱 | 症状 | 处置 |
|---|---|---|
| 在会提前退出的 `head`/`awk` 管道上使用 `set -o pipefail` | 成功时退出码为 141（SIGPIPE） | `common.sh` 中刻意省略 `pipefail` |
| 把状态文件当作 shell 脚本 source | 解析含括号的 `PRETTY_NAME` 时报语法错误 | 用 `state_get` 按键读取取值 |
| 从通配符结果中捕获 inode | 记录到的是符号链接的 inode，陈旧检查虚假通过 | 用 `find -type f -printf '%i'` |
| 在单元循环中用 `printf '%s'` 而不带换行 | 单元名被拼接在一起，重启静默地什么都没做 | 用 `printf '%s\n'` |
| 对桌面单元执行 `systemctl restart` | 会话丢失、VPN 掉线 | 桌面与基础设施单元列在 `DESKTOP_INFRA_PAT` 中，并报告为 deferred |
| 用 `kill` 重启 ISPmanager 面板守护进程 | 面板状态损坏 | 用 `mgrctl -m core --restart srvparam` |

## 禁止事项

- 未经所有者明确同意，删除任务中未提及的文件。
- 在没有前置 `detect.sh` 的情况下运行 `remediate.sh`（变更前状态是强制的）。
- 在真实性闸门未通过时强行安装软件包。
- 自行决定在目标主机上启用自动升级或无人值守重启。
