fix(install): prevent infinite su recursion when running as root#55
Merged
Merged
Conversation
If install_hermes_memory_tencentdb.sh is invoked directly by the root
user (e.g. fresh server with root SSH login), the prior logic:
USERNAME=$(whoami) # → "root"
if [ "$(id -u)" -eq 0 ]; then
su - $USERNAME -c "bash $TEMP_SCRIPT" # → su - root → root → loops
fi
would spin forever: ``su - root`` enters a fresh root shell that re-runs
the script, which sees EUID=0 again and ``su -``-s itself once more.
Symptom (per issue Tencent#20):
[memory-tencentdb] Running as root, switching to root for installation...
[memory-tencentdb] Running as root, switching to root for installation...
... (only Ctrl+C stops it)
Fix:
1. ``USERNAME`` resolution adds two precedence steps before
``$(whoami)`` so admins running ``sudo bash install.sh`` end up
installing for the original user instead of for root:
a. ``INSTALL_AS_USER`` env override (explicit admin choice)
b. ``SUDO_USER`` (sudo's own record of the calling user)
c. ``whoami`` (final fallback)
2. The ``id -u == 0`` branch now skips the ``su -`` step when the
target user is also root — that's the recursion-trigger case. The
script proceeds inline as root for the rest of the install.
3. A new ``elif`` arm logs a clear ``"Running as root; target user is
also root — installing in place."`` so the operator sees what's
happening.
Verified by dry-run simulation of 5 scenarios:
| Case | Branch | USERNAME |
| --------------------------------------- | ------------- | -------- |
| root SSH direct (Tencent#20 reproducer) | INLINE | root |
| non-root user direct | NORMAL | <user> |
| sudo bash install.sh from non-root user | SU | <user> |
| root + INSTALL_AS_USER=bar | SU | bar |
| root + INSTALL_AS_USER=root | INLINE | root |
Closes Tencent#20.
Signed-off-by: 李冠辰 <liguanchen@xiaomi.com>
Collaborator
|
Hi @YOMXXX, 已收到关于 root 安装递归问题的修复 PR,感谢贡献!我们会内部评审后回复。 |
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary | 摘要
修复 #20:root 用户直接跑 `install_hermes_memory_tencentdb.sh` 会触发 `su - root` 无限递归。改为只在目标用户非 root 时 `su -` 切换;如果当前 root 且目标也是 root,直接以 root 跑安装。顺带支持 `SUDO_USER` 与 `INSTALL_AS_USER` env override,让 sudo 场景与管理员场景都正确。
Fix #20: running `install_hermes_memory_tencentdb.sh` as root triggered `su - root` infinite recursion. Now only `su`-switches when the target user is not root; if both are root, installs in place. Also honors `SUDO_USER` and `INSTALL_AS_USER` env overrides so `sudo` and admin scenarios pick the right target.
Root cause
`scripts/install_hermes_memory_tencentdb.sh` (before):
```bash
USERNAME=$(whoami) # → "root" when invoked by root
...
if [ "$(id -u)" -eq 0 ]; then
echo "Running as root, switching to $USERNAME for installation..."
su - $USERNAME -c "bash $TEMP_SCRIPT" # → su - root → loops
fi
```
`su - root` 进入一个新 root shell 重新跑这个脚本,新 shell 看到 `id -u == 0` 又 `su -`,永远停不下来。Issue 报告者 @cuiweiyou 的现象:
```
[memory-tencentdb] Running as root, switching to root for installation...
[memory-tencentdb] Running as root, switching to root for installation...
... (只能 Ctrl+C)
```
Fix
1. USERNAME 解析优先级链
```bash
USERNAME="${INSTALL_AS_USER:-${SUDO_USER:-$(whoami)}}"
```
2. 把 `if` 拆成两条分支
```bash
if [ "$(id -u)" -eq 0 ] && [ "$USERNAME" != "root" ]; then
# 当前 root + 目标非 root → su 切换(原有逻辑)
...
elif [ "$(id -u)" -eq 0 ]; then
# 当前 root + 目标也是 root → 直接 inline 安装,不 su(避免 #20 递归)
echo "Running as root; target user is also root — installing in place."
fi
```
第二条 `elif` 故意让控制流落到下方 "用户阶段(核心安装逻辑)",以 root 身份直接跑剩下的安装步骤。
Compatibility | 兼容性
Dry-run 模拟 5 个场景行为:
dry-run 脚本见 PR description 之外的本地验证(见 commit message)。
`INSTALL_AS_USER` / `SUDO_USER` 是新的输入;既有用户没设这两个的情况下,`USERNAME` 仍然 fall back 到 `whoami` —— 即所有非 root 用户的现有行为完全不变。
Manual test plan
```bash
Before fix(复现 #20):
sudo su - # root shell
bash scripts/install_hermes_memory_tencentdb.sh
→ 反复输出 "Running as root, switching to root..." 直到 Ctrl+C
After fix:
sudo su -
bash scripts/install_hermes_memory_tencentdb.sh
→ 输出 "Running as root; target user is also root — installing in place."
→ 继续正常安装
sudo 场景(顺带改进):
sudo bash scripts/install_hermes_memory_tencentdb.sh
→ 输出 "Running as root, switching to for installation..."
→ 之前会以 root 安装;现在会切回原用户安装
```
Out of scope
DCO
Commit 带 `Signed-off-by: 李冠辰 liguanchen@xiaomi.com`。
Closes #20.