Skip to content

statsig-go: Fix A — NUL-scan + non-canonical ptr guard#10

Closed
nsaini-figma wants to merge 1 commit into
mainfrom
nsaini/fix-a-nul-scan
Closed

statsig-go: Fix A — NUL-scan + non-canonical ptr guard#10
nsaini-figma wants to merge 1 commit into
mainfrom
nsaini/fix-a-nul-scan

Conversation

@nsaini-figma
Copy link
Copy Markdown
Collaborator

Summary

Prototype of the minimal fix for the labmate SIGSEGV in the Rust→Go FFI
string return path. Companion prototype with the structural fix (Fix C —
JNI-style callback) lives on branch nsaini/fix-c-callback. Both
prototypes are draft for side-by-side review.

What changed

  • statsig-go/statsig_ffi.go UseRustString now ignores the inout
    length and calls UnperformantGoStringFromPointer (already in
    tree at statsig-go/internal/ffi_utils.go:14-29). Safe because
    every Rust producer is CString::into_raw, so the buffer is
    NUL-terminated.
  • statsig-go/internal/ffi_utils.go adds non-canonical-address +
    length-bound guards to both GoStringFromPointer and
    UnperformantGoStringFromPointer.

Failure modes covered

  • bad len from purego trampoline → no longer used
  • bad ptr from purego trampoline → returns nil instead of SIGSEGV

Test plan

  • go vet ./... clean (run from statsig-go/)
  • go build ./... builds
  • new unit tests in statsig-go/internal/ffi_utils_test.go (9/9 pass)
  • Validation in labmate staging once tagged as v0.19.4-figma2

Crash signature

runtime.memmove() at src/runtime/memmove_amd64.s:233
runtime.slicebytetostring(buf=0x..., ptr=0x88e50e9746d53405, n=0xd8)
statsig-go/internal/ffi_utils.go:10  GoStringFromPointer
statsig-go/statsig_ffi.go:232        UseRustString
statsig-go/statsig.go:119            (*Statsig).GetFeatureGateWithOptions

0x88e50e9746d53405 is non-canonical for x86-64 userspace, so the
pointer was never valid — purego ABI hazard, not a UAF.

Refs

  • Investigation: ~/nsaini/state/explorations/labmate-statsig-ffi-crash.md
  • Fix design: ~/nsaini/state/explorations/labmate-statsig-ffi-fix.md
  • Companion PR (structural): branch nsaini/fix-c-callback

Defends against the SIGSEGV in labmate caused by garbage ptr/len
returning from purego trampolines.

- UseRustString now ignores the inout length and uses
  UnperformantGoStringFromPointer to scan to NUL (Rust buffers
  are CString::into_raw, so NUL-terminated by construction).
- GoStringFromPointer and UnperformantGoStringFromPointer now
  reject non-canonical x86-64 user addresses and absurd lengths.

See ~/nsaini/state/explorations/labmate-statsig-ffi-fix.md
Fix A and Fix B sections.

Crash signature: github.com/statsig-io/statsig-go-core/internal.
GoStringFromPointer panics in runtime.memmove with ptr=
0x88e50e9746d53405 (non-canonical) under sustained gRPC load
in labmate staging.
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.

1 participant