Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

bug: Agent process environment leaks stale $SHELL into sessions after chsh in startup script

未关闭 适合新手
#24,414 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
76/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
冷清
技术栈
go, zsh
领域
backend, devtools

调研方向

从 agent/agentssh/agentssh.go 中的 CommandEnv 开始,然后阅读 agent/agent.go 中的 updateCommandEnv,以确认继承的环境条目和显式解析的环境条目是如何排序和去重的。让新会话优先使用刚从 /etc/passwd 读取的 shell,然后验证 SSH、Web 终端和重新连接的 PTY 会话在 chsh 后会公开更新后的 $SHELL。

由索引模型根据 Issue 内容生成。

描述

Is there an existing issue for this?
  • I have searched the existing issues
Current Behavior

On first workspace boot, the Coder agent process starts before the startup script runs. At that point, /etc/passwd has the default shell (/bin/bash), and the agent process inherits SHELL=/bin/bash in its own environment.

The startup script then runs chsh -s /usr/bin/zsh, which correctly updates /etc/passwd. However, the agent process's own environment (os.Environ()) still contains SHELL=/bin/bash for the lifetime of the process.

When any session is created (SSH, web terminal, reconnecting PTY), CommandEnv() in agent/agentssh/agentssh.go:

  1. Calls ei.Shell(username) → reads /etc/passwd fresh → returns /usr/bin/zsh ✓
  2. Calls ei.Environ() → returns os.Environ() from agent process → contains SHELL=/bin/bash ✗

The env array is built with os.Environ() first (containing SHELL=/bin/bash), then SHELL=/usr/bin/zsh is appended from the fresh passwd read. This array is passed to updateCommandEnv() in agent/agent.go, which uses first-wins dedup:

for _, env := range current {
    parts := strings.SplitN(env, "=", 2)
    if len(parts) != 2 {
        continue
    }
    if _, ok := envs[parts[0]]; !ok {
        envs[parts[0]] = parts[1]
    }
}

The stale SHELL=/bin/bash from os.Environ() is encountered first and inserted into the map. The correct SHELL=/usr/bin/zsh appended later is silently dropped because the key already exists.

The shell binary used to run the session command is correct (it comes from the shell return value of CommandEnv(), which uses the fresh /etc/passwd read). But the $SHELL environment variable visible inside the session is stale.

Expected Behavior

After chsh changes the login shell in /etc/passwd, all new sessions created by the agent should have $SHELL reflecting the updated value.

The freshly-read shell from /etc/passwd should take precedence over the agent process's inherited $SHELL. Possible fixes:

  1. In CommandEnv(), filter SHELL out of ei.Environ() before appending the fresh value — since the fresh value is explicitly resolved from /etc/passwd, the process-inherited value should never compete with it.
  2. Append ei.Environ() after the explicit SHELL= entry so the first-wins logic picks the correct value.
  3. Have updateCommandEnv() use explicit-wins semantics for variables that are intentionally set by CommandEnv().
Steps to Reproduce
  1. Create a workspace template with a startup script that runs:
    apt-get install -y zsh
    chsh -s /usr/bin/zsh $USER
    
  2. Start the workspace (first boot)
  3. Connect via SSH (or web terminal) after startup completes
  4. Run echo $SHELL → shows /bin/bash (wrong)
  5. Run grep $USER /etc/passwd → shows /usr/bin/zsh (correct in passwd)
Environment
  • Host OS: Ubuntu (workspace image)
  • Coder version: v2.x (tested on latest)
Additional Context
  • The issue only affects the first boot — subsequent workspace restarts have the correct shell already in /etc/passwd when the agent starts.
  • This affects all session types (SSH, web terminal, reconnecting PTY), not just SSH — they all go through CommandEnv() → updateCommandEnv().
  • The root cause is that the agent is a long-running process whose os.Environ() is frozen at startup time, and updateCommandEnv()'s first-wins dedup lets this stale value shadow the explicitly-resolved correct value.
主要语言
Go
星标
16.6k
派生
1.6k
平均合并
1 天 23 小时
30 天内合并 PR
543

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

coder/coder 的其他 Issue

查看 coder/coder 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。