Skip to content

runtime: handle underscore in Linux kernel release strings#170

Open
bradfitz wants to merge 1 commit into
tailscale.go1.26from
bradfitz/underscore
Open

runtime: handle underscore in Linux kernel release strings#170
bradfitz wants to merge 1 commit into
tailscale.go1.26from
bradfitz/underscore

Conversation

@bradfitz
Copy link
Copy Markdown
Member

Some embedded Linux vendors append a platform identifier after an
underscore in the uname release field. For example, Synology NVRs
report a kernel release like "3.4.35_hi3535". parseRelease only
stripped suffixes after '-' or '+', so the patch component
"35_hi3535" failed to parse as an integer and the runtime threw
"failed to parse kernel version from uname" before malloc heap
initialization, making the program unbootable.

Also strip everything after '_', mirroring the existing '-' and '+'
handling.

Regressed in f4de14a / CL 758902 on 2026-03-24, which started
calling parseRelease unconditionally during osinit on 32-bit Linux
to decide between 32- and 64-bit time syscalls.

Updates golang#79612
Updates #162
Updates tailscale/tailscale#6860

Some embedded Linux vendors append a platform identifier after an
underscore in the uname release field. For example, Synology NVRs
report a kernel release like "3.4.35_hi3535". parseRelease only
stripped suffixes after '-' or '+', so the patch component
"35_hi3535" failed to parse as an integer and the runtime threw
"failed to parse kernel version from uname" before malloc heap
initialization, making the program unbootable.

Also strip everything after '_', mirroring the existing '-' and '+'
handling.

Regressed in f4de14a / CL 758902 on 2026-03-24, which started
calling parseRelease unconditionally during osinit on 32-bit Linux
to decide between 32- and 64-bit time syscalls.

Updates golang#79612
Updates #162
Updates tailscale/tailscale#6860
@bradfitz bradfitz requested review from cmol and creachadair May 22, 2026 04:15
Copy link
Copy Markdown
Member

@creachadair creachadair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one non-blocking nit.

Comment thread src/runtime/os_linux.go
// elided.
func parseRelease(rel string) (major, minor, patch int, ok bool) {
// Strip anything after a dash or plus.
// Strip anything after a dash, plus, or underscore. Some
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change seems fine, but we no longer actually follow semver grammar, strictly speaking (to be fair, Synology et al. started it). Maybe note this in the doc comment above? E.g.,

// parseRelease parses a dot-separated version number.
// It follows semver syntax, but allows the minor and patch
// versions to be elided, and accepts "_" as a separator for
// pre-release labels in addition to "-".

or words to that effect.

(Likewise we don't handle build labels either, though if we got one of those on a kernel release we probably have bigger issues 😅)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, this code from Go (which is like 10 years old) never did semver... it also parse "4.5" without a patch.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think we need to match the spec, my comment was mostly just about updating the comment. But it's unexported, so certainly not essential.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants