Commit Graph
4 Commits
Author SHA1 Message Date
Francois Marier e8ebe6aba1 ssh/tailssh: parse UIDs consistently in isRootUser()
Since the incubator parses the UID in base 0 via flags.IntVar()
and isRootUser() uses base 10, it was possible to get inconsistent
results between the two using non-base 10 numbers.

Updates tailscale/corp#50380

Change-Id: I9b2fb16bc37153df7b695533cc73a3499cb774eb
Signed-off-by: Francois Marier <francois@tailscale.com>
2026-10-26 20:06:51 -07:00
Mike Jensen 1f9df5e6d4 ssh/tailssh: unify defaultPathForUser to use isRootUser (#21928)
This change unifies all root checks in `ssh/tailssh` to use `isRootUser`. This ensures we consistently avoid the `== "0"` check and protects us in any future root check changes (previously missed in #21919).

Updates tailscale/corp#50380

Change-Id: I598e4394cf3a779e622fa208378b33afee8723e3

Signed-off-by: Mike Jensen <mikej@tailscale.com>
2026-10-24 15:54:15 -06:00
James Tucker d90ffb62af ssh/tailssh: treat numerically-zero uids as root in isRootUser
An NSS uid like "00" passed the string != "0" check but parses to 0 in
the incubator, so a session could bypass non-root checks and run as
root. Compare the uid numerically instead; non-numeric uids keep the
previous behavior.

Updates tailscale/corp#50380

Signed-off-by: James Tucker <james@tailscale.com>
2026-10-24 13:23:22 -07:00
Brad Fitzpatrick 664ba588ab ssh/tailssh: split the OS-specific parts of the server into their own files
The main server file mixed portable session handling with Unix details:
sending SIGHUP to end a session, decoding exec.ExitError, the euid check
for whether the process can switch users, agent forwarding's chown of the
socket, and reading /etc/ssh host keys as root. Those now sit behind small
functions (hangupProcess, waitProcess, canSwitchToLocalUser,
handleSSHAgentForwarding, systemHostKeyFile, isRootUser) in the new
process_unix.go, along with the incubator's forwarded-environment pipe
helpers, and the session's *exec.Cmd moves into an embedded osSessionState
struct defined there, so that the portable code no longer refers to the
process representation at all.

user.go keeps only the portable userMeta and userLookup; the login shell
and default PATH logic moves to user_unix.go. The SFTP child entrypoint and
its stdio adapter, which incubator.go and incubator_plan9.go each had a
copy of, move to sftp.go. The c2n usernames handler gains a hook for
platforms that list users some other way than /etc/passwd.

The agent socket's uid and gid are parsed as 31-bit rather than 32-bit
unsigned values so that the conversion to int for os.Chown cannot
overflow on 32-bit platforms, which is the pattern CodeQL flags.

Updates #cleanup

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I4c7e2b9a0d3f5e1c8b6a4d2f0e9c7b5a3d1f8e6c
2026-09-15 19:32:40 -07:00