➜ go version
go version go1.19.6 linux/amd64
➜ uname -a
Linux dmitry-desktop 6.1.18-200.fc37.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Mar 11 16:09:14 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
I am unable to run compiled golang app using setuid/setguid bits of the executable file.
I have set +s
permission on the executable main
file, owned by test
user. I'm trying to invoke that file from dmitry
user expecting the file would use test
uid, but it's not happening.
[test@dmitry-desktop setguid]$ whoami
test
[test@dmitry-desktop setguid]$ id
uid=1001(test) gid=1002(test) groups=1002(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[test@dmitry-desktop setguid]$ ./main
[test@dmitry-desktop setguid]$ ls -la
total 1356
drwxrwxr-x. 2 test test 100 Mar 26 14:07 .
drwxrwxrwt. 48 root root 1780 Mar 26 14:07 ..
-rwsr-sr-x. 1 test test 1.9M Mar 26 14:16 main
-rw-r--r--. 1 test test 225 Mar 26 13:58 main.go
-rw-r--r--. 1 test test 9 Mar 26 14:07 test_file
[test@dmitry-desktop setguid]$ go build main.go
[test@dmitry-desktop setguid]$ chmod u+s main
[test@dmitry-desktop setguid]$ chmod g+s main
[test@dmitry-desktop setguid]$ ls -la main
-rwsr-sr-x. 1 test test 1943252 Mar 26 14:18 main
[test@dmitry-desktop setguid]$ ./main
Real UID: 1001
Effective UID: 1001
Real UID: 1001
Effective UID: 1001
now I run the same main from a different user
➜ whoami
dmitry
✗ /tmp/setguid/main
Real UID: 1000
Effective UID: 1000
Real UID: 1000
Effective UID: 1000
panic: open /tmp/setguid/test_file: permission denied
goroutine 1 [running]:
main.check(...)
/tmp/setguid/main.go:14
main.main()
/tmp/setguid/main.go:32 +0xe5
main.go
package main
import (
"os"
"syscall"
"log"
"fmt"
"time"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
printdelay()
errgid := syscall.Setuid(syscall.Getuid())
if errgid != nil {
log.Fatal(errgid)
os.Exit(1)
}
printdelay()
d1 := []byte("hello\ngo\n")
err := os.WriteFile("/tmp/setguid/test_file", d1, 0644)
check(err)
}
func printdelay() {
fmt.Printf("Real UID: %d\n", syscall.Getuid())
fmt.Printf("Effective UID: %d\n", syscall.Geteuid())
time.Sleep(7 * time.Second)
}
then I tried the following:
sudo /sbin/setcap cap_setuid=ep main
chown root:root main
chmod +s main
ls -la main
-rwsr-sr-x. 1 root root 1943124 Mar 26 14:28 main
then I modify my go file to
// errgid := syscall.Setuid(syscall.Getuid())
errgid := syscall.Setuid(1001)
and trying to invoke it:
✗ id
uid=1000(dmitry) gid=1000(dmitry) groups=1000(dmitry),10(wheel),969(plugdev),971(wireshark),975(docker) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c102
➜ ./main
Real UID: 1000
Effective UID: 1000
2023/03/26 14:33:04 operation not permitted