In May 2022, a security flaw (known as CVE-2022-29526) was found in Go (or Golang), a popular programming language. This vulnerability exposes a problem with the way Go's Faccessat function checks user privileges, which could let programs wrongly believe a file is accessible when it's not.
Understanding this bug is important for anyone building or running Go code, especially when handling sensitive files or permissions.
What Is Faccessat?
Faccessat is a system call used to check if a file can be accessed by the current user for reading, writing, or executing. In Go, it's exposed internally for use in checking file permissions.
For example
package main
import (
"os"
"syscall"
)
func main() {
err := syscall.Faccessat(-1, "/etc/shadow", syscall.O_RDONLY, )
if err != nil {
println("Can't access")
} else {
println("Can access")
}
}
What's the Vulnerability?
The bug centers around the flags parameter in Faccessat. If a non-zero flag (like AT_EACCESS) is passed, Go before 1.17.10 and 1.18.x before 1.18.2 *ignores* the flag and doesn't check access properly. That could make your Go program *think* someone can access a file, when they actually can't.
Imagine you wrote a Go web app that checks if a user has access to a file before serving it
func userCanAccess(filepath string) bool {
return syscall.Faccessat(-1, filepath, syscall.O_RDONLY, unix.AT_EACCESS) == nil
}
On vulnerable Go versions, AT_EACCESS is silently ignored and the check is incorrect. That means your security check is broken, and people might get access to files they shouldn't!
Here's a quick proof-of-concept that demonstrates the bug
package main
import (
"fmt"
"os"
"syscall"
)
func main() {
filename := "/root/secret.txt" // File only root can access
// Try to check using AT_EACCESS
err := syscall.Faccessat(syscall.AT_FDCWD, filename, syscall.O_RDONLY, 1) // 1 == AT_EACCESS
if err == nil {
fmt.Println("Bug: This user should *not* have access, but Faccessat reports access.")
} else {
fmt.Println("Safe: Access denied as expected.")
}
}
On affected Go versions: This might incorrectly print "Bug: This user should *not* have access, but Faccessat reports access."
Why?
The Go implementation just ignores the flags value, so your code thinks access is allowed even if it isn't.
How to Fix or Protect
* Upgrade Go:
- At least to Go 1.17.10 or Go 1.18.2
* Don't rely on Faccessat security checks on old Go
* If you can't upgrade:
Avoid using non-zero flags in Faccessat
- Re-implement access checks using direct file open/test logic
References
- Go security advisory - go#52574
- NVD Entry for CVE-2022-29526
- Go 1.17.10 release notes
- Go 1.18.2 release notes
- Faccessat man page (Linux)
Conclusion
CVE-2022-29526 is an easy-to-overlook, but serious bug in Go if you're using file access checks. The fix is simple: upgrade your Go compiler to a patched version. Always keep your tools up to date, especially when security is involved!
If you think you might be affected, audit your Go code for the use of Faccessat with flags, and upgrade as soon as you can.
Timeline
Published on: 06/23/2022 17:15:00 UTC
Last modified on: 08/19/2022 12:50:00 UTC