Why I can not drop sudo root privileges

permissionsrootsetuidsudosystem-calls

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