1
package main

import (
    "fmt"
    "os"
    "os/exec"
    "syscall"
)

func main() {
    os.Setuid(1000)
    cmd := exec.Command("/bin/sh")

    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    cmd.Env = []string{"PS1=-[ns-process]- # "}
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWNS |
            syscall.CLONE_NEWUTS |
            syscall.CLONE_NEWIPC |
            syscall.CLONE_NEWPID |
            syscall.CLONE_NEWNET |
            syscall.CLONE_NEWUSER,
        UidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      os.Getuid(),
                Size:        1,
            },
        },
        GidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      os.Getgid(),
                Size:        1,
            },
        },
    }

    if err := cmd.Run(); err != nil {
        fmt.Printf("Error running the /bin/sh command - %s\n", err)
        os.Exit(1)
    }
}

Above is my code,but get the result is "Fork/exec /bin/sh operation not permitted" when running the program in root user.But it run correctly with uid 1000.

os: 5.15.55-1-MANJARO go version: 1.18.3

Hamza Anis
  • 2,475
  • 1
  • 26
  • 36

1 Answers1

0

see https://walac.github.io/golang-patch/

The reason is that the Credential struct has a Groups field representing an array of supplementary group ids to pass to setgroups, and when Credential != nil, setgroups gets always called, even if didn’t set the Groups property.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 04 '23 at 12:29