Using the os/exec
package, I want to run an external command on a *nix OS with another user instead of root. (The main process runs under root user).
The external command runs by go app. But my app can not read /proc/pid/smaps
file, following error:
panic: open /proc/2962/smaps: permission denied
goroutine 6 [running]:
main.memwatch(0xc000094000, 0xc00007a0c0)
/src/main.go:41 0x298
created by main.main
/src/main.go:25 0x18f
exit status 2
Here is my code:
// main.go
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
)
func main() {
cmd := exec.Command("sleep", "3")
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Credential: &syscall.Credential{Uid: 65534, Gid: 65534}, // External command expect run with `nobody` instead of `root` for security reason
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Start()
done := make(chan struct{})
go memwatch(cmd, done)
if err != nil {
panic(err)
}
cmd.Wait()
close(done)
}
func memwatch(cmd *exec.Cmd, done <-chan struct{}) {
// Reuse the reader so we don't have to close and reopen it all the time
smaps, err := os.Open(fmt.Sprintf("/proc/%d/smaps", cmd.Process.Pid))
if err != nil {
panic(err)
}
defer smaps.Close()
for {
select {
case <-done:
return
default:
fmt.Println("running")
time.Sleep(10 * time.Millisecond)
}
}
}
I'm tired. Anyone here for help, please.
CodePudding user response:
I test my code inside a docker container that doesn't have SYS_PTRACE
capability. That's why the error shows. The error was gone when I added the SYS_PTRACE
capability for that container.