I am debugging a program and not quite sure why I can not drop privileges.
I have root permissions via sudo
and I can call setgid/setuid
, but the operation [is]
is not supported.
Basic code to reproduce (golang):
package main
import (
"fmt"
"os"
"strconv"
"syscall"
)
func main() {
if os.Getuid() != 0 {
fmt.Println("run as root")
os.Exit(1)
}
uid, err := strconv.Atoi(os.Getenv("SUDO_UID"))
check("", err)
gid, err := strconv.Atoi(os.Getenv("SUDO_GID"))
check("", err)
fmt.Printf("uid: %d, gid: %d\n", uid, gid)
check("gid", syscall.Setgid(gid))
check("uid", syscall.Setuid(uid))
}
func check(message string, err error) {
if err != nil {
fmt.Printf("%s: %s\n", message, err)
os.Exit(1)
}
}
Example output:
$ sudo ./drop-sudo
uid: 1000, gid: 1000
gid: operation not supported
System info:
$ uname -a
Linux user2460234 4.15.0-34-generic #37-Ubuntu SMP Mon Aug 27 15:21:48 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Best Answer
Your programming language simply does not support such things.
It's complex to do this stuff on Linux, because of the architecture of Linux. The C libraries (e.g. GNU and musl) hide this complexity. It continues to be one of the known problems with threads on Linux.
The Go language does not replicate the mechanism of the C libraries. The current implementation of those functions is not a system call, and has not been since 2014.
Further reading