headscale/hscontrol
SAY-5 01e548e030 state: avoid nil deref in registration handlers when old user is missing
Mirror the guard from HandleNodeFromPreAuthKey in HandleNodeFromAuthPath.
Both functions log the old user's name in the "different user" branch
when an existing NodeStore entry under the same machine key belongs to
another user. UserView.Name dereferences the backing User pointer
unconditionally, so when the cached node was loaded with a non-nil
UserID but a nil User (Preload join missed the row, or upstream code
left the snapshot in that shape), the log call panics with a nil-pointer
dereference at hscontrol/types/types_view.go:97.

The panic is caught by the http2 server's runHandler for the noise
control plane, so the process keeps running but every retry produces a
new panic — production has observed bursts of ~1.9k panics per hour
during a tailscaled reconnect loop. The gRPC/OIDC entry has no equivalent
recover and would surface the panic to the caller.

Guard both call sites with oldUser.Valid() and fall back to an empty
old-user name when the pointer is nil. The "Creating new node for
different user" log line still includes the existing node ID, hostname,
machine key, and new user, so operator visibility is preserved.

Add reproduction tests for both handlers seeding the orphan shape
directly into NodeStore via PutNodeInStoreForTest.

Co-Authored-By: Kristoffer Dalby <kristoffer@dalby.cc>
2026-05-06 07:23:02 +01:00
..
assets assets: fix logo alignment and error icon centering 2026-04-13 17:23:47 +01:00
capver capver: regenerate for tailscale v1.96 2026-04-08 13:00:22 +01:00
db all: rephrase prose to fit codebase voice 2026-04-29 16:22:19 +01:00
derp all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
dns Fix typo in comment about fsnotify behavior 2026-02-27 15:23:06 +01:00
mapper state: switch consumers to NodeStore primary routes 2026-04-29 18:08:39 +01:00
policy testdata: drop unused uppercase SSH-*.hujson fixtures 2026-05-05 11:59:01 +01:00
servertest servertest: cover via-grant exit-node visibility end-to-end 2026-04-30 19:22:45 +01:00
state state: avoid nil deref in registration handlers when old user is missing 2026-05-06 07:23:02 +01:00
templates all: rephrase prose to fit codebase voice 2026-04-29 16:22:19 +01:00
types oidc: handle groups claim as string or array (FlexibleStringSlice) 2026-05-04 15:26:53 +02:00
util hscontrol: route hostname handling through dnsname and NodeStore 2026-04-18 15:12:21 +01:00
app.go app: add security headers middleware 2026-04-17 16:31:49 +01:00
app_test.go app: add security headers middleware 2026-04-17 16:31:49 +01:00
auth.go hscontrol: route hostname handling through dnsname and NodeStore 2026-04-18 15:12:21 +01:00
auth_tags_test.go state: note tagged-path coverage and self-healing behaviour for #3199 2026-04-29 13:06:38 +01:00
auth_test.go state: avoid nil deref in registration handlers when old user is missing 2026-05-06 07:23:02 +01:00
debug.go debug: explain URLIsNoise choice in ping callback 2026-04-17 16:31:49 +01:00
grpcv1.go state: replace zcache with bounded LRU for auth cache 2026-04-10 14:09:57 +01:00
grpcv1_test.go all: rephrase prose to fit codebase voice 2026-04-29 16:22:19 +01:00
handlers.go oidc: render HTML error pages for browser-facing failures 2026-04-13 17:23:47 +01:00
handlers_test.go oidc: render HTML error pages for browser-facing failures 2026-04-13 17:23:47 +01:00
metrics.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
noise.go noise: reject non-HEAD on PingResponseHandler 2026-04-17 16:31:49 +01:00
noise_test.go policy/v2: align SSH check action with SaaS wire format 2026-04-17 16:31:49 +01:00
oidc.go oidc: render HTML error pages for browser-facing failures 2026-04-13 17:23:47 +01:00
oidc_confirm_test.go oidc: add confirmation page for node registration 2026-04-10 14:09:57 +01:00
oidc_template_test.go oidc: render HTML error pages for browser-facing failures 2026-04-13 17:23:47 +01:00
oidc_test.go oidc: make email verification configurable 2025-12-18 11:42:32 +00:00
platform_config.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
poll.go types: add node.expiry config, deprecate oidc.expiry 2026-04-08 13:00:22 +01:00
poll_test.go poll: fix poll test linter violations 2026-03-12 01:27:34 -07:00
tailsql.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
templates_consistency_test.go Update links to Tailscale documentation 2026-04-18 09:33:41 +02:00