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