Inspecting and Dropping Privileges
Print your uid/gid, read the umask, see how it trims a new file's mode, then drop privileges the safe way (group before user) only if you started as root.
package main
import (
"fmt"
"os"
"os/user"
"syscall"
)
func main() {
fmt.Println("uid:", os.Getuid(), "gid:", os.Getgid(), "euid:", os.Geteuid())
if u, err := user.Current(); err == nil {
fmt.Printf("user: %s (uid %s)\n", u.Username, u.Uid)
}
// Read the umask by setting it to 0 and immediately restoring it.
old := syscall.Umask(0)
syscall.Umask(old)
fmt.Printf("umask: %04o\n", old) // umask: 0022
// Create a file requesting 0666 and see what the umask actually leaves.
f, _ := os.CreateTemp("", "perm")
defer os.Remove(f.Name())
f.Close()
os.Chmod(f.Name(), 0666)
info, _ := os.Stat(f.Name())
fmt.Printf("mode after chmod 0666: %v\n", info.Mode().Perm()) // -rw-rw-rw-
// Dropping root only makes sense if you actually started as root.
if os.Geteuid() == 0 {
if err := syscall.Setgid(65534); err != nil { // drop group first
fmt.Println("setgid:", err)
}
if err := syscall.Setuid(65534); err != nil { // then drop user
fmt.Println("setuid:", err)
}
fmt.Println("dropped to euid:", os.Geteuid())
} else {
fmt.Println("not root, skipping privilege drop")
}
}Save the code as main.go and run it:
go run main.goExpected output:
uid: 1000 gid: 1000 euid: 1000
user: alice (uid 1000)
umask: 0022
mode after chmod 0666: -rw-rw-rw-
not root, skipping privilege dropYour uid, gid, and username will differ. Run it under sudo to see the privilege-drop path actually execute.