Hasty Briefsbeta

Bilingual

When the compiler lies: breaking memory safety in safe Go

6 hours ago
  • #Go Compiler
  • #Security Bugs
  • #Memory Safety
  • The author discovered two compiler bugs in Go (up to version 1.26.1) that broke memory safety using only safe Go code, without unsafe imports, CGO, custom assembly, or data races.
  • Bug 1 involved the 'prove' optimization pass incorrectly handling signed integer wrap in loops, allowing array bounds checks to be eliminated when indices could become negative, leading to control-flow hijacking.
  • Bug 2 occurred during SSA lowering, where a no-op conversion caused the compiler to skip careful copying for overlapping arrays, resulting in memory corruption and potential exploitation.
  • Both bugs stemmed from the compiler mistakenly upgrading 'probably safe' to 'proved safe', highlighting that memory safety depends on the entire toolchain, not just the language.
  • The author found that the root cause of Bug 1 was a change they had introduced over three years earlier, revealed by 'git blame', shifting their initial thrill to a humbling realization.
  • The Go security team responded quickly to the reports (within minutes), and the author plans to publish full details after fixed releases are widely available.