Preface: Go is garbage collected instead of manual memory management which is not suitable for a kernel.
Golang is useful for carrying out programming for scalable servers and large software systems. The Golang programming language was built to fill in the gaps of C++ and Java that Google came across while working with its servers and distributed systems.
Background: Go does have an extensive library, called the runtime, that is part of every Go program. The runtime library implements garbage collection, concurrency, stack management, and other critical features of the Go language.
The Go scheduler is part of the Go runtime, and the Go runtime is built into your application. This means the Go scheduler runs in user space, above the kernel.
For Go to “call the kernel directly” can exploit so-called ABI of the H/W and OS combo. For example: On linux, making a syscall requires filling a set of CPU registers with certain values, doing some other arrangements and then issuing the SYSENTER CPU instruction.
The 64-bit x86 Linux ABI supports the following entry points:
- SYSCALL from 64-bit code;
- interrupt 0x80 from 32- and 64-bit code;
- SYSENTER from 32-bit code.
Vulnerability details: On Unix platforms, the Go runtime does not behave differently when a binary is run with the setuid/setgid bits. This can be dangerous in certain cases, such as when dumping memory state, or assuming the status of standard i/o file descriptors. If a setuid/setgid binary is executed with standard I/O file descriptors closed, opening any files can result in unexpected content being read or written with elevated privileges. Similarly, if a setuid/setgid program is terminated, either via panic or signal, it may leak the contents of its registers.
Official announcement: For details, please refer to the link- https://pkg.go.dev/vuln/GO-2023-1840