Skip to content

fix(hutils): capget writing past its buffer in TunAllowed - #157

Merged
hiddify-com merged 1 commit into
hiddify:mainfrom
heppycat:fix-capget-overflow
Oct 28, 2026
Merged

hiddify-com merged 1 commit into
hiddify:mainfrom
heppycat:fix-capget-overflow

Conversation

@heppycat

Copy link
Copy Markdown
Contributor

TunAllowed() (desktop Linux) calls capget with LINUX_CAPABILITY_VERSION_3 and a single unix.CapUserData. For versions 2 and 3 the kernel always writes two __user_cap_data_struct (capabilities 0-31 and 32-63, 24 bytes; see capget(2)), so it writes 12 bytes past data, onto the stack.

The second struct isn't empty in practice. For a process with full capabilities it holds Effective:511, for capabilities 32-40 (I checked this through the same call in rootlesskit, rootless-containers/rootlesskit#658).

I haven't seen this crash Hiddify; the file is linux && !android, so Android isn't affected. The same code in Xray-core's WireGuard client (XTLS/Xray-core#7274) corrupted a saved return address on 32-bit ARM and crashed every time, so it's worth fixing.

The fix passes [2]unix.CapUserData and reads data[0]. CAP_NET_ADMIN is 12, so the result doesn't change.

Tested: gofmt is clean, and go vet ./v2/hutils/ passes for linux/amd64, arm64 and arm. I also ran the patched TunAllowed() on its own. It returns false unprivileged and true inside unshare -rn, where the process has CAP_NET_ADMIN.

TunAllowed asks for LINUX_CAPABILITY_VERSION_3, for which the kernel
always writes two CapUserData (caps 0-31 and 32-63, 24 bytes), but it
passed a single one (12 bytes), so the kernel wrote 12 bytes past it.
@hiddify-com
hiddify-com merged commit 36ad8d0 into hiddify:main Oct 28, 2026
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.

2 participants